我试图从python正则表达式解析字符串,但当字符串包含“时无法解析”:&引用;

我试图从python正则表达式解析字符串,但当字符串包含“时无法解析”:&引用;,python,regex,string,re,Python,Regex,String,Re,我有 但当字符串中有:“”时,我将正则表达式修改为“61:[A-Za-z0-9\/,\-\.:]{1,}:86:[A-Za-z0-9\/.\-:]{1,}”,然后在一个列表中给出它的全部内容 string = ":61:2002190219C45612.4S202EXCOL3654628815//CT56748005:86:/BENM/Unitech Imports/REM//58970.047:61:2002190219C30000S103LCADV5674920204//CT567

我有

但当字符串中有:“”时,我将正则表达式修改为
“61:[A-Za-z0-9\/,\-\.:]{1,}:86:[A-Za-z0-9\/.\-:]{1,}”
,然后在一个列表中给出它的全部内容

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 

冒号似乎是匹配结束时的唯一指示符,因此允许冒号作为匹配的一部分将删除分隔符。也就是说,您可以通过将量词
{1,}
更改为非贪婪(即,返回尽可能短的匹配,而不是最长的匹配)来获得所需的结果。一般来说,这是一个有点粗糙的解决方案,并表明您可能需要重新考虑您的解析策略。但是如果在每个
{1,}
之后添加一个
,您将再次获得两个匹配项

此外,您还可以将
{1,}
缩短为
+

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' ]

由于模式以
61:
开头,并且只出现了一次
:81:
,因此您可以使用替换来匹配字符类
[a-Za-z0-9\/,\u.-]
或仅在不直接后跟
61:
86:
时使用负前瞻匹配

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:/']

这其中哪一部分令人惊讶?“:”是唯一指示一个字符串在哪里停止,下一个字符串在哪里开始的东西。只要允许一个匹配包含冒号,Python就无法知道它不是一个长匹配。默认情况下,正则表达式函数返回可能最长的匹配项。“正则表达式函数总是返回可能最长的匹配项”-不是真的-默认情况下是的,它们是贪婪的,但您可以通过放置?在模式元素之后,例如,
*
是贪婪的,但
*?
不是贪婪的-它将尝试匹配最短的序列。yYup,将我的注释从“始终”编辑为“默认”。感谢您的注释,@barny.
[\w/,.-]
而不是
[A-Za-z0-9\/,\u.-]
@Navneet如果通过单击帮助解决您的问题,请随意选择✓ 在这个答案的左边。注意,你得到2接受一个解决方案。谢谢@第四只鸟。它工作正常。我还需要所有的:61标记,后面没有:86-string=”:61:2002190XCOL3654628815//CT505:86:/BENM/Imports/REM//58:61:2002190219C300S103L:V5674//CT56748006:86:/BENM/Gravity Imports/REM//INV/FEB20/446301:61:200219C30000S103LCADV567204//C7006:“预期o/p->61:200219C30000S103LCADV567204//C7006使用此正则表达式-61:(?:[\w/,.-)::(?!:61:)::(?!:61:)*->这是给:61标签,后面跟着:86。请建议我犯错误的地方,基本上我想要-字符串组合:61:86标签和:61字符串,后面不跟着:86@Navneet您可以在
$
末尾添加一个锚点,以断言字符串
61:(?:[\w/,.-]|:(?!61:| 86:)的结尾*$
或者,您可以使用负前瞻来断言在匹配61:之后不再出现:61:和:86:
61:(?!)*(?@Thefourthbird我已经试过了-这只适用于:61在字符串末尾。:61也可以在两者之间,有两个:61标记在下面示例中,这个正则表达式只解析1。Thanks@Mark里德-我现在明白了贪婪与非贪婪的区别-但我需要从一个:61标签到下一个:61标签的内容,上面的解决方案不包括:86标签。
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:/']
61:(?:[\w /,.-]|:(?!61:|86:))*:86:(?:[A-Za-z0-9 /.-]|:(?!61:|86:))*