Jordan Sitkin
Jordan Sitkin

Reputation: 2343

How would I implement this regex in ColdFusion (or Java)?

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

Upvotes: 4

Views: 410

Answers (3)

Boomerang Fish
Boomerang Fish

Reputation: 121

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]);
  }
}

Upvotes: 4

lins314159
lins314159

Reputation: 2520

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}");

Upvotes: 1

rook
rook

Reputation: 67019

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

Upvotes: 0

Related Questions