Very basic question but this macro language is confusing to me.
I have a text object, $ref, which contains a string, "Lesson 29". I want to extract the digits (which can be n to nnn) into another text object, call it $refNum. How do I do that? Is there a simple way to use some kind of "find" command with "\d+"? I looked at "substring", having been used to "substr" in another program language, but I can't understand the documentation. A find with regex would be better since it would trap the digits regardless of length.
Extract digits from a text object
-
- Posts: 34
- Joined: 2005-10-05 15:05:51
- Location: Portland, OR
- Contact:
-
- Posts: 34
- Joined: 2005-10-05 15:05:51
- Location: Portland, OR
- Contact:
Re: Extract digits from a text object
Alternatively, I could use a find & replace operation that would replace "Lesson " with "W-", resulting in "W-29".
Re: Extract digits from a text object
Hello Allen,
This being Nisus you will be doing this with Find/Replace no matter what.
To start with the solution, this will get you what you want:
Basically, you can do Find/Replace on text objects in more or less the same way that you would do them in the app itself. So if we compare the following two things:
they will both find the first string of digits in the relevant text object. The menu command "Find" will actually create a selection in the GUI, while the latter will return a 'virtual' selection, in the form of a TextSelection object. If you catch the result(s) as follows:
The former will still create the selection in the GUI, and $result will return the number of hits. The latter will return a TextSelection object—or in the case of .findAll an array of TextSelection objects.
So one way to extract a number from a text object would be:
To understand why you need to do this this way, you will need to check on how TextSelections work (which I wrote about in other threads).
This method can hit its limit when the pattern you are trying to find is more complicated. But ".find" has another method that turns the found bits into variables. You could do the same like this:
In this case using the "¢" option—only possible with single hit .find, not with .findAll—returns the found bits as number variables: $0 for the whole thing, $1 for the first match, $2 for the second, etc.
The "¢" option also allows you to name the variables yourself. For this you need to use (?<variable_name> … ) match parentheses. This is only possible using PowerFind Pro. That leads to the above mentioned solution.
This being Nisus you will be doing this with Find/Replace no matter what.
To start with the solution, this will get you what you want:
Code: Select all
$ref.find "(?<refnum>d+)", "E¢"
Code: Select all
Find "\d+", "E"
$mytext.find "\d+", "E"
Code: Select all
$result = Find "\d+", "E"
$result = $mytext.find "\d+", "E"
So one way to extract a number from a text object would be:
Code: Select all
$mytextselection = $mytext.find "\d+", "E"
$refnum = $mytextselection.substring
This method can hit its limit when the pattern you are trying to find is more complicated. But ".find" has another method that turns the found bits into variables. You could do the same like this:
Code: Select all
$mytextselection = $mytext.find "\d+", "E¢"
$refnum = $0
The "¢" option also allows you to name the variables yourself. For this you need to use (?<variable_name> … ) match parentheses. This is only possible using PowerFind Pro. That leads to the above mentioned solution.
philip
Re: Extract digits from a text object
PS: I should also mention that you can use this with more complicated Find patterns. So if you wanted to ensure that the digits are after the string "Lesson " you could do it like this:
If this doesn't match anything in $ref, then $refnum will be undefined.
Code: Select all
$ref.find "Lesson (?<refnum>\d+)", "E¢"
philip
- martin
- Official Nisus Person
- Posts: 5227
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
Re: Extract digits from a text object
Thanks to Philip for covering this topic and giving some nice examples. I'll only reply to add a few technical terms and links.
This works because of the ¢ option specific to the Nisus macro language. It converts the standard regular-expression (regex) full match \0 into a $0 macro variable. For more details on the ¢ and $ options please see the Find & Replace section of the macro reference.
This works because of the explicit capture in the regular expression. The \1 back-reference is converted into a $1 macro variable.
This utilizes the named capture feature of regular expressions. The Nisus macro language picks up your capture's name and creates appropriate local variables.
Code: Select all
$text = 'Lesson 11'
$text.find '\d+', 'E¢'
Prompt $0
Code: Select all
$text = 'Lesson 21'
$text.find 'Lesson (\d+)', 'E¢'
Prompt $1
Code: Select all
$text = 'Lesson 31'
$text.find 'Lesson (?<lessonNumber>\d+)', 'E¢'
Prompt $lessonNumber
-
- Posts: 34
- Joined: 2005-10-05 15:05:51
- Location: Portland, OR
- Contact:
Re: Extract digits from a text object
Thank you lots for this extensive and detailed explanation!
At first I tried all the variations and they all failed. After a LONG time and many tries, I finally realized that, in copying your code from the forum, the quotation marks came through as double smart quotes. I used your first example, changing the smart quotes to straight quotes, and it worked perfectly. Thank you!
At first I tried all the variations and they all failed. After a LONG time and many tries, I finally realized that, in copying your code from the forum, the quotation marks came through as double smart quotes. I used your first example, changing the smart quotes to straight quotes, and it worked perfectly. Thank you!