-1

Upon validation using regular expression in Java, I need to return true for height having values :

  • 80cm
  • 80.2cm
  • 80.25cm

My regular expression is as follows :

(\d)(\d?)(.?)(\d?)(\d?)(c)(m)

However if I pass in height as 71-80cm , the regular expression returns true too.

What change should I make to the regular expression to return false when height is 71-80cm ?

  • 1
    Change `.` to `\.` because an unescaped `.` matches more or less everything. – Dawood ibn Kareem Mar 31 '20 at 19:36
  • You give three examples of strings you wish to match. Presumably you want to match other strings as well. You show us one string you don't want to match, but that leaves a nearly-infinite number of strings in no-man's land. Do you want to match `"80 cm"`? `"80cmmm"`? `"-80.2cm"` in `"difference is -80.2cm"`? `"08cm"`?. You need to tell us the *pattern* of strings that are to be matched... – Cary Swoveland Mar 31 '20 at 20:05
  • ...Here's an example (which may or may not be what you want): "I wish to match substrings of the form `"abcm"` that are not followed by a letter, where `"cm"` is a literal, `"b"` is the string representation of a non-negative float or integer (e.g., `"80"` or `"80.25"`, but not `"08"` or `".25"`) and `"a"` is a character other than `"-"`, `"+"` and `"."`, unless `"b"` is at the beginning of the string, in which case `"a"` is an empty string". Please edit your question to clarify. Think of this as practice for writing code specifications, where you must be precise. – Cary Swoveland Mar 31 '20 at 20:05
  • To whoever closed this question: escaping the period is only one aspect of the issues with this expression, and in no way does the linked question address them all. – oriberu Mar 31 '20 at 22:18

3 Answers3

0

. matches any character, so you need to have \\. or just \. depending on the source. Check out: Java RegEx meta character (.) and ordinary dot?

Furthermore, additional changes need to be made such that e.g. 8025cm is not accepted if that is what you want.

Pete
  • 569
  • 3
  • 9
  • Thanks Pete & Dawood. Escaping the dot . i.e \\. instead of just dot . made height validation fail with the new regex which is (\d)(\d?)(\.?)(\d?)(\d?)(c)(m) – ajay vasudevan Mar 31 '20 at 20:18
0

I assume that the OP wishes to match substrings of the form

abcm

where:

  • "cm" is a literal;
  • "cm" is not followed by a letter;
  • "b" is the string representation of a non-negative float or integer (e.g., "80" or "80.25", but not "08" or ".25"); and
  • "a" is a character other than "-", "+" and ".", unless "b" is at the beginning of the string, in which case "a" is an empty string.

If my assumptions are correct you could use the following regex to match b in abcm:

(?<![-+.\d])[1-9]\d*(?:\.\d+)?cm(?![a-zA-Z])

Demo

The regex engine performs the following operations:

(?<!          # begin negative lookbehind
  [-+.\d]     # match '-', '+', '.' or a digit
)             # end negative lookbehind
[1-9]         # match digit other than zero
\d*           # match 0+ digits
(?:\.\d+)     # match '.' followed by 1+ digits in a non-cap grp
?             # optionally match non-cap grp
cm            # match 'cm'
(?![a-zA-Z])  # match a letter in a negative lookahead

If my assumptions about what is required are not correct it may be evident how my answer could be adjusted appropriately.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
0

Ok, let's take your expression and clean it up a little. You don't need all the capturing groups (..), since all you're interested in is validating the complete string. For that reason you should also enclose the expression in line beginning ^ and line end $ anchors, so your expression can't match inside a larger string. Lastly, you can group the period and trailing digits together (?:), since you won't get one without the other as per your example data. Which gets us:

^\d\d?(?:\.\d\d?)?cm$

See regex demo.

Then in Java, that check could look like this:

boolean foundMatch = subjectString.matches("^\\d\\d?(?:\\.\\d\\d?)?cm$");
oriberu
  • 1,186
  • 9
  • 6