3

I have strings similar to; First Half Goals 1.5/2. The text at the beginning can be anything so cannot depend on that as part of the RegEx as it varies. What I want to do is to match the number sequence at the end. Test samples would be:

  • 5
  • 0.5/1
  • 2.5/3
  • 147

The sequence can either contain a slash or it cannot. If it contains a slash, there must be a value after it - either integer or decimal. The value before the decimal (if one is present) can be any number of digits - \d+ - but the value after should must be 0 or 5 - (0|5). The 1st value before the slash (/) is either an integer or a decimal. If the sequence contains a slash, then the number after is also either a integer or a decimal. All values are positive.

The main point of this RegEx is that I need it to only match once. The was the RegEx I was using:

(\d(\.(0|5))?\/\d(\.(0|5)))|(\d\.(0|5))|(\d)

The issue with the regex above is that the example string I use; First Half Goals 1.5/2 matched twice. Once on the 1.5 & the 2nd on the 2. I have now altered it to be this:

\d+(\.(0|5))?(\/?\d+(\.(0|5))?)?

This is slightly better but if I give the test sample; 1.6/2, it will match 6/2. This will be because the decimal section on the former number is optional. I'm not sure if a lookbehind would come in handy here, I don't have much experience with them. Sadly the text beforehand is so unpredictable otherwise I could trim the string to only get the wanted substring & then match from the start of the string but can't do that. An outline of what should match & what should not:

1         // Match
5.5       // Match
7.8       // No Match
0/0.5     // Match
147/147.5 // Match
2.        // No Match
6.5/      // No Match
7.0/8     // Match
10.0      // Match
1./2.5    // No Match
5./6      // No Match
/157      // No Match
/4.5      // No Match

I've tried to explain as best I could but if you need more details then I'll provide them

wmash
  • 3,662
  • 3
  • 26
  • 60

1 Answers1

2

In Node.js, RegExp supports lookbehinds and you may use

/\b(?<!\d\.|\/)\d+(?:\.[05])?(?:\/\d+(?:\.[05])?)?$/

See the regex demo

Details

  • \b - word boundary
  • (?<!\d\.|\/) - no digit + dot or a slash are allowed immediately to the left of the current location
  • \d+ - one or more digits
  • (?:\.[05])? - an optional sequence of
    • \. - a dot
    • [05] - 0 or 5
  • (?:\/\d+(?:\.[05])?)? - an optional sequence of
    • \/\d+ - a / and 1+ digits
  • (?:\.[05])? - an optional sequence of a dot and then 0 or 5
  • $ - end of string.
Wiktor Stribiżew
  • 561,645
  • 34
  • 376
  • 476
  • Great answer! I think 1 I left out that shouldn't match though is `/147.5`. If I put that on where the slash proceeds a value, it will match the value. I would expect that it wouldn't as it looks in the RegEx that there must be 1+ digits proceeding it but it does match. If you amend it to not match that, I'll accept your answer – wmash May 18 '20 at 13:46