-1

Using Swift 4.2, trying to match a regex similar to 1980 / 1989 / 2019 etc., but what I need is a match only if sequence is not followed by "p" ? what I'm trying ... "(?:[1-2]{1}[0,9]{1}[0-9]{1,2})\1(?![p])"

espr3ss0
  • 33
  • 1
  • 3
  • Assuming Swift regex supports it, your negative lookahead at the end looks correct. What is wrong with your current pattern? – Tim Biegeleisen Apr 25 '19 at 14:15
  • Possible duplicate of [Regular expression to match a line that doesn't contain a word](https://stackoverflow.com/questions/406230/regular-expression-to-match-a-line-that-doesnt-contain-a-word) – Paul Benn Apr 25 '19 at 14:51
  • Returns nothing. – espr3ss0 Apr 25 '19 at 15:14
  • Is this about regular expressions or swift? Depending on which it is could you clarify your question with some sample data (and code if relevant) and given result vs expected result – Joakim Danielson Apr 25 '19 at 15:16

2 Answers2

0

After plenty of testing I found a solution ... "(?:([1-2]{1}[0,9]{1}[0-9]{2})(?![p]))"

espr3ss0
  • 33
  • 1
  • 3
0

Let's consider this string :

let str = """
10 Hello 980 world,
1975 Hello 1980 world,
1985p Hello :1995 world,
2000 Hello 2005p world,
2010 Hello 2015 world,
2019 Hello 2020 world,
2999
"""

Let's declare this regex :

let pattern = "19[89]{1}[0-9]{1}(?![p])|20[01]{1}[0-9]{1}(?![p])"
let regex = try! NSRegularExpression(pattern: pattern)

Here are the different parts of the pattern :

  • 19 matches the characters 19 literally,
  • [89]{1} matches a single character in the list 89, to limit the years to the 1980s and 90s,
  • [0-9]{1} one digit for the year,
  • (?![p]) negative lookahead, meaning: not followed by p,
  • | logical OR,
  • 20 matches the characters 20 literally,
  • [01]{1} matches a single character in the list 01, to limit the years to the 2000s and 2010s,
  • [0-9]{1} one digit for the year,
  • (?![p]) negative lookahead, meaning: not followed by p.

Now, let's get the matches :

let matches =
    regex.matches(in    : str,
                  range : NSRange(location: 0, length: str.utf16.count))

for match in matches {
    let range = match.range
    if let swiftRange = Range(range, in: str) {
        let name = str[swiftRange]
        print(name)
    }
}

Which prints in the console :

1980
1995
2000
2010
2015
2019

Bear in mind that this would still match things like 1990s, 1999a, 19999999, since you've only asked to not be followed by p.

ielyamani
  • 17,807
  • 10
  • 55
  • 90