1

I need to return the first percentage, and only the first percentage, from each row in a file.

  1. Each row may have one or two, but not more than two, percentages.
  2. There may or may not be other numbers in the line, such as a dollar amount.
  3. The percentage may appear anywhere in the line.

Ex:

Profits in California were down 10.00% to $100.00, a decrease from 22.6% the prior year.
Profits in New York increased by 0.9%.
Profits in Texas were up 1.58% an increase from last year's 0.58%.

I can write a regex to capture all occurrences:

[0-9]+\.[0-9]+[%]+?

https://regex101.com/r/owZaGE/1

The other SO questions I've perused only address this issue when the pattern is at the front of the line or always preceded by a particular set of characters

What am I missing?

RSax
  • 328
  • 3
  • 12

3 Answers3

2
/^.*?((?:\d+\.)?\d+%)/gm

works with a multiline flag, no negative lookbehind (some engines don't support non-fixed width lookbehinds). Your match will be in the capture group.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 2
    You can get rid of the false negative by combining a negative lookahead with `.`: [`^(?:(?!\d+%).)*?((?:\d+\.)?\d+%)`](https://regex101.com/r/boyL7I/1/) – Hao Wu May 27 '21 at 00:50
  • 2
    Or simply use `.*?` instead of `[^%]*?` since it's non-greedy – Hao Wu May 27 '21 at 00:56
1

Mine is similar to you except I allowed numbers like 30% (without decimal points)

\d+(\.\d+)?%

I don't know what language you are using, but in python for getting the first occurrence you can use re.search()

Here is an example:

import re

pattern = r'\d+(\.\d+)?%'
string = 'Profits in California were down 10.00% to $100.00, a decrease from 22.6% the prior year.'

print(re.search(pattern, string).group())
S.B
  • 13,077
  • 10
  • 22
  • 49
0

I was able to solve using a negative lookbehind:

(?<!%.*?)([0-9]+\.[0-9]+[%]+?)
RSax
  • 328
  • 3
  • 12
  • 1
    The `[%]+` can just be `%`. It seems unlikely that you'd need to match more than 1 consecutive percent sign. – ggorlen May 26 '21 at 23:11