1

I've created a Regexp to validate a direction in degrees, between -359 and +359 (with optional sign). This is my regex:

const QString xWindDirectionPattern("[+-]{0,1}([0-9]{1,2}|[12][0-9]{2}|3[0-5][0-9])");

Now, I want to add two decimal numbers, in order to write numbers from -359.99 to +359.99. I've tried something like appending \.[0-9]{1,2}|[0-9]{1,3} but It does not work.

I'd like to have optional decimal point so I can have

23.3   valid
23.33  valid
23     valid
23.333 not valid

I've read some other questions, like this one, but I'm not able to modify the example to match a number range, like in my case. How can I achieve this result?

Thanks in advance for your replies.

How can achieve this?

Community
  • 1
  • 1
Jepessen
  • 11,744
  • 14
  • 82
  • 149

3 Answers3

2

I've created a Regexp to validate a direction in degrees, between -359 and +359

No, you can't. You shouldn't. You are using the wrong tool. Regex cannot do the kinds of validation, which require it to dig into the semantics of the characters.

Regex can only process and match text, but cannot identify what they actually mean. Basically Regex are good for parsing regular language, and bad for almost everything else.

For e.g.:

  • A Regex can match 3 digits, but it would be extremely impractical to use it to match 3 digits that fall in range - [259, 634]. For that you would need to know the meaning of each individual digits in that number.
  • A Regex can match a pattern for date like - \d\d/\d\d/\d\d, but it cannot identify which part is date, and which part is month.
  • Similarly, it can find you two numbers x and y, but it cannot identify, whether x < y or not.

The task as above require you to understand the meaning of the text. Regex can't do that.

Well, of course you have come up with a regex for sure, but as you can see it is highly un-flexible. A little change in your requirement, will screw both - the regex and you.

You should better use corresponding language features - constructs like if-else to make sure you are reading degrees in that range, and not regex.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • I validate numbers after their insertion, but I want to do this because I've a grid cell in which I must put this value and I must to create a validator in order to avoid that the user write wrong data while writing, like inserting letters or putting invalid values. I think that regexp is a good tool for this, but maybe you can suggest something better? – Jepessen Jul 30 '13 at 14:43
  • @Jepessen. Well, some kind of validation you can do by regex, for e.g., testing that a user doesn't any alphabet, where only digits are required, or a field should start with a particular letter, only contain characters from a given set, and should be of a specified length. But some validation like I said, to identify the `range` of a number can't be done. You should use proper language construct for that. BTW, What language are you using? – Rohit Jain Jul 30 '13 at 16:24
  • Also see [this](http://programmers.stackexchange.com/q/113237/66382) and [this](http://stackoverflow.com/q/7553722/1679863) post. – Rohit Jain Jul 30 '13 at 16:27
1

You can do this:

[+-]{0,1}((?:[0-9]{1,2}|[12][0-9]{2}|3[0-5][0-9])(?:\.[0-9]{1,2})?)

This will allow an a decimal point followed by one or two digits. You'll probably also want to use start and end anchors (^ / $) to ensure that there are no characters other than this pattern in your string—without this, 23.333 would be allowed because 23.33 matches the above pattern:

^[+-]{0,1}((?:[0-9]{1,2}|[12][0-9]{2}|3[0-5][0-9])(?:\.[0-9]{1,2})?)$

You can test it out here.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • I can write 359.88, but I can also write, for example, 6334, but in this case no decimal point is allowed. – Jepessen Jul 30 '13 at 14:29
  • @Jepessen I thought the whole idea was to support the range between -359.99 and 359.99. Why would 6334 be allowed? – p.s.w.g Jul 30 '13 at 15:01
  • Infact I'm saying that I can write also 6334, but I should not be allowed. – Jepessen Jul 30 '13 at 15:06
  • @Jepessen Okay, thanks for clearing that up. You're probably seeing that because it's matching `63` inside `6334`. See my note about using start and end anchors (`^` / `$`). My second pattern would not allow `6334` at all. – p.s.w.g Jul 30 '13 at 15:10
  • I've just tried, it allows me to write invalid values like 99999. I've checked a bit and If I write a value in my range it works well, but I can also write a value out of range, and in this case decimals are not allowed. – Jepessen Jul 30 '13 at 15:19
  • Are you using the start / end anchors like I suggested? It seems to work fine for me. Test it here: http://regexpal.com/?flags=gm&regex=%5E%5B%2B-%5D%7B0%2C1%7D((%3F%3A%5B0-9%5D%7B1%2C2%7D%7C%5B12%5D%5B0-9%5D%7B2%7D%7C3%5B0-5%5D%5B0-9%5D)(%3F%3A%5C.%5B0-9%5D%7B1%2C2%7D)%3F)%24&input=23.3%0A23.33%0A23%0A23.333%0A6334%0A99999 – p.s.w.g Jul 30 '13 at 15:22
  • I don't know what to say... maybe a problem related to QRegExp and QRegExpValidator? – Jepessen Jul 30 '13 at 15:27
  • @Jepessen That's possible. I'm not really familiar with that particular regex engine / validator. According to [this](http://harmattan-dev.nokia.com/docs/library/html/qt4/qregexpvalidator.html) the anchors would be assumed. Perhaps it's simply confused and is considering it 'Intermediate'. – p.s.w.g Jul 30 '13 at 18:28
  • Ok. I'll try to check it in the Qt forum and then return here if I will have any news. – Jepessen Jul 31 '13 at 12:31
1

Try [+-]?([1-9]\d?|[12]\d{2}|3[0-5]\d)(\.\d{1,2})?.

[+-]?          Optional Sign
[1-9]\d?       1 or 2 digit number
[12]\d{2}      100 to 299
3[0-5]\d       300 to 359
(\.\d{1,2})?   Optional decimal point followed by 1 or two digits
Phylogenesis
  • 7,775
  • 19
  • 27