using regex to find square bracketsI have a customer who wants to extract the numbers for spec limits. He can do it when the text uses parentheses but not for square brackets. Since square brackets, "[" and "]", are special regex characters, I thought that using the escape character "\" or "\\" would help but I could not get it to work.
The text he is searching might look like [0.080, 1.20] and he wants to use regex to get 0.080 and 1.2.
His current formula for finding left parentheses, "(" in the text looks like this:
Regex( :Text, "((?<=\().+(?=\,))" )
For right parentheses, ")", he uses
Regex( :Text, "((?<=\,).+(?=\)))" )
How can these formulas be modified to find "[" or "]"?
After he gets that, he'd also like to be able to find "<", ">", "+", "-" and "+/-".
Any help would be appreciated.
Thanks!
Re: using regex to find square bracketsThis always trips me up because \[ is the escape sequence to demarcate a string. If you escape it first, you can use it to signify a regex metacharacter
Num( Regex( :String, "\!\[([0-9\.eE\+\-]+)", "\1" ) )
for the first number
Num( Regex( :String, "\!\[([0-9\.eE\+\-]+)\s*,([0-9\.eE\+\-]+)", "\2" ) )
for the second.
Re: using regex to find square bracketsHi Charlie,
Do you have an idea of what the text looks like? The customer might not even need regex. In settings where this is the case, the resulting JSL is often much easier to implement and maintain.
For example:
Names Default To Here(1);
text = "this is a bunch of text with some data in it between brackets [2.3, 4.5] like so.";
specTxt = word(2, text, "[]");
specLo = num(word(1, specTxt, ","));
specHi = num(word(2, specTxt, ","));
show(specLo, specHi);
Re: using regex to find square bracketsBut why use a tack hammer when a 16-lb sledge hammer makes a bigger bang?
Re: Using regex to find square bracketsHas! So true.
Re: using regex to find square bracketsThis is a great question for the user to post to the Discussions board to see the speed and quality of the responses they'll get from the larger JMP user community.
For me personally, I never did learn Regex so I rely on the Character functions for most string manipulation. In particular the Word() function works wonders for me.
If you learn only one Formula Editor function, Word() is the one
Re: using regex to find square bracketsThis is a great idea. I'd also be curious to see how often folks do what I did, answer the question directly, rather than think about what the user is trying to do, to come up with a simple and more elegant solution. It's always better to understand what the user needs and not necessarily what they want.
Re: using regex to find square bracketsHere is another example of how a regex might be used.
Names Default to Here( 1 );
// source
string = "My spec limits are [0.080,1.20] for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),(\d*\.?\d*)", "\2" ) );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Re: using regex to find square bracketsThanks Brady! I tried your solution and it works. I like the simplicity. Is there a way to have word search for either a "[" or a "("? I think that is closer to what the customer is looking for.
thanks again!
Charlie
Re: using regex to find square bracketsThanks Don! Your solution works for square brackets. Is there a way to have it search for either "(" or "[" so that it would work for either case?
thanks!
Charlie
Re: using regex to find square bracketsMark-
I had a little trouble getting your solution to work. I have attached a sample data table. Could you take a look and let me know what I'm doing wrong?
thanks,
Charlie
Re: using regex to find square bracketsThanks Jeff. I don't know regex at all and I also try to use the character functions. However, I wanted to answer the customer's question using a technique very similar to the way he was doing it so that he could apply it easily.
I did encourage him to post it on the community. We'll see what happens.
thanks!
Charlie
Re: using regex to find square bracketsHi Charlie,
The word() function has 3 arguments, the last of which, the delimiter set, is optional. This is a quoted string containing all of the delimiters you want to consider. So the user would place brackets and parens into this string.
To see how word( ) breaks up a function, it can help to examine what is returned by the words() function. Words() returns a list of all the text fragments, after delimiting.
For example:
word (2, "Hit the road jack") returns "the".
word(2, "Hit the road jack", "") returns "i", because the empty string is used when you want to break the text into individual characters.
word(1, "abc/def[ghi]klm", "[]()") returns "abc/def"... if you look at words( "abc/def[ghi]klm", "[]()" ), you will get
{ "abc/def", "ghi", "klm" } as the result.
Hope this helps.
Cheers,
Brady
Re: using regex to find square bracketsIf you really want to use Regex, the following string can be used for upper or lower
"[\!\[|\(]([0-9\.eE\+\-]+)\s*,\s*([0-9\.eE\+\-]+)"
the only difference will be the second argument, "\1" for the lower and "\2" for the upper. To understand what's going on, think of the expression as being in four parts
[\!\[|\(]
[a|b] will match either a or b, both the square brackets and parentheses are special characters, so they have to escaped by using the backslash. Because the sequence \[ is also special in JSL, that needs the ! to indicate it's not a special sequence.
([0-9\.eE\+\-]+)
The parentheses capture the expression contained in it. This is what the \1 refers to. Again, the square brackets are used to designate a character set. In this case it's any one or more (due to the + at the end) of a number, period (special character escaped), plus (ditto), minus (ditto), lower or upper case E. If there are any characters that I forgot that can be used to signify a number, put them in here.
\s*,\s*
zero or more spaces, a comma, zero or more spaces
([0-9\.eE\+\-]+)
Same expression as the first one captured. It is reference by \2. The great thing is, once you've gotten this far, you can stop. No need to capture the closing bracket or parenthesis (as far as I can tell). You could if you wanted to.
All this said, I'd use Brady's solution. It's more succinct and easier to understand. You'll need to add the comma into the set of delimiters, i.e.,
"[(,])"
Re: using regex to find square bracketsYour previous example did not include a space after the comma. Here is the corrected script example:
Names Default to Here( 1 );
// source 1
string = "My spec limits are [0.080, 1.20] for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" ) );
Show( lsl, usl );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Show( lsl, usl );
// source 2
string = "My spec limits are (0.080, 1.20) for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" ) );
Show( lsl, usl );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Show( lsl, usl );
I attached your data table with the corrected formulae.
Re: using regex to find square bracketsThis is a good example of how Regex can be tricky to implement, without a good understanding of the data underneath. The presence/absence of a space made a difference.
Now suppose that any legitimate numerical format had to be supported. In this case the Regex would get uglier, because you'd have to account for scientific notation, negatives, periods (or not), etc.
In such cases, a combination of JSL functions and Regex may get the job done more easily than either alone.
For example, in the JSL below:
1) Substitute changes brackets and parens to braces (the list operator... important in point 3)
2) Regex grabs the braces and what they contain, assumed to be a pair of legitimate numbers in whatever format
3) Parse converts the string returned by Regex into a JSL expression that assigns the list contents to specLo and specHi.
txt = "My spec limits are [-4.087e-3, 1.20] for this CQA.";
{specLo, specHi} = Parse( Regex( Substitute( txt, "(", "{", "[", "{", ")", "}", "]", "}" ), "\\!{.*\\!}" ) );
-Brady
Re: using regex to find square bracketsThanks for your help!