Dip
Dip

Reputation: 25

Invalid regular expression: look-behind requires fixed-width pattern

Regex pattern used:

(?<!cart .*)(?<!order .)(\b\d{4,12}\b)

Examples:

so the cart number is 12344567 that it
my cart number is 1234
order number note down 12345
order 12345
credit card is 0000
4444
the 5456

Expected output:

0000
4444
5456

Here i don't want number that starts with word order or cart that can range from 4 to 12.

Upvotes: 3

Views: 204

Answers (1)

The fourth bird
The fourth bird

Reputation: 163362

If you want to use Python with a infinite quantifier in the lookbehind, you can use the PyPi regex module.

You don't need the capture group, and you have to repeat the dot for the order part (?<!order .*)

But using an alternation, you can use a single lookbehind:

(?<!(?:cart|order) .*)\b\d{4,12}\b

See a regex demo.

Example

import regex

pattern = r"(?<!(?:cart|order) .*)\b\d{4,12}\b"

s = ("so the cart number is 12344567 that it\n\n"
    "my cart number is 1234\n\n"
    "order number note down 12345\n\n"
    "order 12345\n\n"
    "credit card is 0000\n\n"
    "4444\n\n"
    "the 5456")

print(regex.findall(pattern, s))

Output

['0000', '4444', '5456']

Another option is to use an alternation with re.findall and filter out the empty values, or use re.finditer and loop the values checking for a group 1 value.

An example with re.findall, where you match what you don't want and capture in group 1 what you want to keep using a for comprehension:

import re

pattern = r"^.*\b(?:cart|order)\b.*|(\b\d{4,12}\b)"

s = ("so the cart number is 12344567 that it\n"
            "my cart number is 1234\n"
            "order number note down 12345\n"
            "order 12345\n"
            "credit card is 0000\n"
            "4444\n"
            "the 5456")

print([s for s in re.findall(pattern, s, re.M) if s])

Output

['0000', '4444', '5456']

Upvotes: 2

Related Questions