I am trying to parse string from python regex-Not able parse when string contain ":"

Viewed 75

I have

string = ":61:2002190219C45612.4S202EXCOL3654628815//CT56748005:86:/BENM/Unitech Imports/REM//58970.047:61:2002190219C30000S103LCADV5674920204//CT56748006:86:/BENM/Gravity Imports/REM//INV/FEB20/446301"
pattern = "61:[A-Za-z0-9 \/,\-_\.]{1,}:86:[A-Za-z0-9 \/\.\-]{1,}"
re.findall(pattern , string) # - > this is giving list with 2 element 

but when string has ":" in it, i modified regex to "61:[A-Za-z0-9 \/,\-_\.:]{1,}:86:[A-Za-z0-9 \/\.\-:]{1,}", then its giving full content in one list.

modified_string = ":61:2002190219C45612.4S202EXCOL:3654628815//CT56748005:86:/BENM/Unitech Imports/REM//58970.047:61:2002190219C30000S103LCAD:V5674920204//CT56748006:86:/BENM/Gravity Imports/REM//INV/FEB20/446301"

I have tried multiple option but not able to get required output.

Expected o/p

re.findall(pattern,modified_string)
# => ['61:2002190219C45612.4S202EXCOL:3654628815//CT56748005:86:/BENM/Unitech Imports/REM//58970.047','61:2002190219C30000S103LCAD:V5674920204//CT56748006:86:/BENM/Gravity Imports/REM//INV/FEB20/446301' ]
2 Answers

As the pattern starts with 61: and there is a single occurrence of :81:, you might use an alternation to match any of the listed chars from the character class [A-Za-z0-9 \/,_.-] or only match a : when not directly followed by either 61: or 86: using a negative lookahead.

61:(?:[\w /,.-]|:(?!61:|86:))*:86:(?:[A-Za-z0-9 /.-]|:(?!61:|86:))*

Regex demo

The colon appears to be the only indicator that you've hit the end of a match, so allowing a colon to be part of a match removes your delimiter. That said, you can maybe get the desired result by changing your quantifiers {1,} to be non-greedy (that is, to return the shortest possible match instead of the longest). This is, in general, a somewhat hacky solution and indicates you might need to rethink your parsing strategy. But if you add a ? after each {1,}, you get two matches again.

Also, you can shorten {1,} to +.

pattern = re.compile(r"61:[A-Za-z0-9 \/,\-_\.:]+?:86:[A-Za-z0-9 \/\.\-:]+?")
pattern.findall(string)
#=> ['61:2002190219C45612.4S202EXCOL3654628815//CT56748005:86:/',
     '61:2002190219C30000S103LCADV5674920204//CT56748006:86:/']
Related