2

I am working on a music generation project. Input only contains alpha characters and digits. The regex is one of the requirements we've set as a limitation.

So, this gets me numbers under 26 but if a number like 27 shows up it still picks up the 2 and the 7. How can I exclude all numbers 26 and up? Thanks!

/[0-2][0-5]|[1-9]/g 

I should add...this is part of a large string with letters and spaces before and after the numbers. So I have to recognize the numbers in the string and pull them out. Only using string.prototype.match() and regex. Long story. Thx

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Fedreg
  • 523
  • 2
  • 6
  • 15
  • I guess you can't do that, but will be easier work with it's numeric value rather than simply text. Anyway read this http://stackoverflow.com/questions/8592488/regex-how-can-i-match-all-numbers-greater-than-49 – exoddus Aug 25 '16 at 06:30
  • That doesn't seem to work on all option. Need to use regex unfortunately. Not my choice. Thanks though – Fedreg Aug 25 '16 at 06:51
  • How is the input data structured? Are the numbers separated by a special character (e. g. is there at least one space between the numbers)? – muton Aug 25 '16 at 07:00
  • @Fedreg: See [my answer with explanations](http://stackoverflow.com/a/39138675/3832970). – Wiktor Stribiżew Aug 25 '16 at 07:04
  • `\b(1?\d|2[0-5])\b` – SamWhan Aug 25 '16 at 07:08

4 Answers4

3

Your [0-2][0-5]|[1-9] regex pattern matches any sequence of a 0-2 digit followed with 0-5 digit OR a 1-9 digit anywhere inside the string.

To match individual values from 1 till 25, you may use

/\b(0?[1-9]|1[0-9]|2[0-5])\b/g

See the regex demo

Pattern details:

  • \b - leading word boundary
  • (0?[1-9]|1[0-9]|2[0-5]) - either of the alternatives:
    • 0?[1-9] - an optional leading 0 followed with a digit from 1 to 9
    • 1[0-9] - 10 till 19
    • 2[0-5] - 20 till 25
  • \b - trailing word boundary
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Wiktor, thank you for the explanations. The problem is that there will be spaces before and after the numbers. I'm sorry if I did not make that clear and wasted your time. Have only used regex sparingly and didn't realize this would be so complex. I will re-edit my post – Fedreg Aug 25 '16 at 07:08
  • So, you are extracting them? Replace `^` and `$` with `\b`. If there are other issues, feel free to drop a comment. – Wiktor Stribiżew Aug 25 '16 at 07:09
  • That did it! Again, sorry for lack of clarity! – Fedreg Aug 25 '16 at 07:11
  • You know, that is not a perfect solution if your input is a mess. If there are dates or float values or version numbers, you would probably like to exclude those, and that means, you'd have to use something like `/(?:^|[^\d.])(0?[1-9]|1[0-9]|2[0-5])(?![.\d])/g` and use the `RegExp#exec` in a loop to get the capture group contents out of each match. This won't match `2` in `2. Text` though, so further adjustments might be necessary. – Wiktor Stribiżew Aug 25 '16 at 07:13
  • 1
    No, it is a music generation project. Only alpha characters and digits. It is just a bit of an experiment and regex is one of the requirements we've set as a limitation. If it expands we will surely use a better method that regex. Your answer was very helpful though – Fedreg Aug 25 '16 at 07:17
  • You can also match leading 0 (zero or more) with the * quantifier: `/\b(0*[1-9]|0*1[0-9]|0*2[0-3])\b/g`. This will match 22 and 0022, if for you it's the same number. – lordofmax Nov 04 '20 at 00:08
2

Ahh... so you have right now... 0-5, 10-15, 20-25 OR 0-9

You had the right idea, just wrong application of the idea.

([01]?[0-9]|2[0-5])

// should omit those pesky one-offs you're seeing as mentioned in the comments.
^([01]?[0-9]|2[0-5])$
\b([01]?[0-9]|2[0-5])\b

// if you also want to exclude 0...
^([1-9]|1[0-9]|2[0-5])$
\b([1-9]|1[0-9]|2[0-5])\b

That figuratively says any number between 0 thru 19(w/ or w/o preleading 0's) OR 20-25.

Steve Kline
  • 805
  • 4
  • 11
  • Thanks for the help. I see...thanks for explaining. this seems to work up until 19 but returns 20-25 as individual integers ( 2,0 2, 5 etc. ). Sadly I have to use regex for this. – Fedreg Aug 25 '16 at 06:50
  • ^([01]?[0-9]|2[0-5])$ or leading/trailing \b – Steve Kline Aug 25 '16 at 06:54
  • Steve, thanks. I edited my post to note that there could be preceding and following spaces. Apologies for not including that originally. Didn't realize it would matter; new to regex. – Fedreg Aug 25 '16 at 07:12
  • So the \b would be ideal for you. I write complex regex's to parse thru logs to find important troubleshooting methods on unix/linux hosts at work. \b is a barrier... like a white space. Meaning this should be an isolated finding next to other stuff. – Steve Kline Aug 25 '16 at 07:17
  • Ya I'll remember that \b for next time! Thanks – Fedreg Aug 25 '16 at 07:19
0

I would suggest something along the lines of (take or remove some of the elements I added as I don't know your exact requirements)

/^(([ 01]?[1-9])|2[0-5])$/
  • The ^...$ to match the entire input to avoid matching single digits of a two-digit input
  • ? to allow for a one-digit input
  • the | to allow for the two cases "first digit = 0 or 1" and "first digit = 2"

But over all there certainly are better tools than regex to do this job, like parsing the number and doing a simple comparison.

piet.t
  • 11,718
  • 21
  • 43
  • 52
0

^\d$|^1\d$|^2[0-6]$ will match 0-26.

However, this is not a problem you should be solving with regex. A better solution is to test the number with operators like < or <=:

myNum < 27 // is 0-26
rockerest
  • 10,412
  • 3
  • 37
  • 67