views:

58

answers:

3

I found this very handy regular expression on regexlib.com, but i'm at a loss as to how to implement it in my app.

(?:(?:(?<Feet>\d+)[ ]*(?:'|ft)){0,1}[ ]*(?<Inches>\d*(?![/\w])){0,1}(?:[ ,\-]){0,1}(?<Fraction>(?<FracNum>\d*)\/(?<FracDem>\d*)){0,1}(?<Decimal>\.\d*){0,1}(?:\x22| in))|(?:(?<Feet>\d+)[ ]*(?:'|ft)[ ]*){1}

I tested it out using their online testing tool, and it does indeed do everything I need. Pasting it in as a parameter to ColdFusion's REFind() predictably did not work and returned a useless error message.

I'm working in ColdFusion, so I have access to Java classes if needed. Answers in Java or ColdFusion would both be helpful.

A good sample string would be something like: 5' 1/2"

EDIT

I need to make use of the groups in the regex in order to extract the data as opposed to simply using it to validate a string. I guess this means i should using REMatch()? Please excuse my lack of experience with regex!

EDIT 2

It seems that using REFind() with this expression:

(?:(?:(\\d+)[ ]*(?:'|ft)){0,1}[ ]*(\\d*(?![/\\w])){0,1}(?:[ ,\\-]){0,1}((\\d*)\\/(\\d*)){0,1}(\\.\\d*){0,1}(?:\\x22| in))|(?:(\\d+)[ ]*(?:'|ft)[ ]*){1}

is not finding matches for most of the test data i give it, including ones that return matches using the regexlib.com tester: 1ft 2-3/4 in, 2' 3 4/5", 3ft, 4', 5 in, 6", 7.125 in, 3ft 4.5 in

A: 

Java's String object supports regex's. Sting.match(), String.replaceAll() and String.replaceFirst().

Rook
+1  A: 

Seems like the expression you had was in C# syntax, which supports named groups (eg. (?<Decimal>\.\d*)). Java doesn't, and treats them as something entirely different. Since the named groups are not used anyway, it's simply a matter of removing the naming part (eg. (?<Decimal>\.\\d*) becomes (\.\\d*)).

Pattern.compile("(?:(?:(\\d+)[ ]*(?:'|ft)){0,1}[ ]*(\\d*(?![/\\w])){0,1}(?:[ ,\\-]){0,1}((\\d*)\\/(\\d*)){0,1}(\\.\\d*){0,1}(?:\\x22| in))|(?:(\\d+)[ ]*(?:'|ft)[ ]*){1}");
lins314159
I should been more clear in my original question: I DO need to make use of the groups in order to extract the matched values. Do you know how I can do this in the Java syntax?
DustMason
You'll have to the group number (starting from 1). To get the Inches group, you would use `matcher.group(2)`.
lins314159
+4  A: 

The ?<foo> syntax is not supported in ColdFusion. I'm not familiar with that syntax, but it looks like it is being used to assign names to captured subexpressions. For example, the first subexpression is the number representing feet, so it has the ?<Feet> tag. You can remove those tags without affecting what the regex matches.

I haven't tested it, but all the other elements I see in that regex are supported in ColdFusion, so REFind() should work after removing all the ?<foo> tags. Accessing the subexpressions is of course supported by using the "returnsubexpressions" argument. See the standard CF docs on REFind().

As an aside, the regex seems a little verbose. {0,1} is rare, as ? means the same thing. {1} is even rarer, as it is the default for groupings and thus can be omitted completely.

ADDENDUM

regex = "(?:(?:(\\d+)[ ]*(?:'|ft)){0,1}[ ]*(\\d*(?![/\\w])){0,1}(?:[ ,\\-]){0,1}((\\d*)\\/(\\d*)){0,1}(\\.\\d*){0,1}(?:\\x22| in))|(?:(\\d+)[ ]*(?:'|ft)[ ]*){1}";
subs = REFind(regex,input,1,"True");
if (subs.pos[1] eq 0) {
  found = "False";
} else {
  found = "True";
  feet = Mid(input,subs.pos[2],subs.len[2]);
  inches = Mid(input,subs.pos[3],subs.len[3]);
  fraction = Mid(input,subs.pos[4],subs.len[4]);
  fracNum = Mid(input,subs.pos[5],subs.len[5]);
  fracDem = Mid(input,subs.pos[6],subs.len[6]);
  decimal = Mid(input,subs.pos[7],subs.len[7]);
  if (feet is "") {
    // Use the _other_ feet
    feet = Mid(input,subs.pos[8],subs.len[8]);
  }
}
Boomerang Fish
thanks, it does indeed work without those tags, as @lins314159 pointed out. do you know how i might be able to access those groups using a different syntax?
DustMason
wow thanks! found is coming back false though, given my sample input from above: 5' 1/2". using the tester at regexlib.com this yields a set of matches.
DustMason
IIRC, the ?<foo> structure is a Microsoft extension, and not supported by anything outside of C#/VB/etc. I'm not entirely sure how to google ?<foo> to check, though. :-)
Ben Doom