高效的正则表达式,用于仅减少由Python中特定分隔符分隔的完全重复的短语

问题描述

假设我的购物清单如下:

lines="""
''[[excellent wheat|excellent wheat]]''
''[[brillant corn|Tom's brilliant corn]]''
''[[spicy chips|spicy fries/chips]]''
"""

仅当产品为完全重复时,才应将购物清单上的产品减少为非重复,即“ [[[优质小麦|优质小麦]]”-> ” [[[优质小麦]]”。不完整的重复项应保持原样。

我已经浏览了一些other threads,但找不到理想的解决方案。

我想像这样逐行评估多行字符串的一部分,

for i in range(0,100):
    lines[i] = regexHere(lines[i]) #regex expr here
    print lines[i]

,我希望获得以下输出

''[[[优质小麦]]''
” [[[灿烂的玉米|汤姆的灿烂玉米]]”
” [[[辣薯条|辣薯条/薯条]]”

谢谢。

编辑:这适用于给定的示例。如果购物清单位于包含其他格式的随机行的清单中,该怎么办?

lines="""
==///Listings==/?
assadsadsadsa
adasdsad
</test>
''[[excellent wheat|excellent wheat]]''
''[[brilliant corn|Tom's brilliant corn]]''
</separation>
Remember to purchase this if on offer
''[[jub|jub/ha]]'',''[[barley|barley/hops]]''
zcxcxzcxz
"""

解决方法

为此,您确实不需要正则表达式–您可以使用直接的字符串操作:

lines="""
''[[excellent wheat|excellent wheat]]''
''[[brilliant corn|Tom's brilliant corn]]''
''[[spicy chips|spicy fries/chips]]''
"""

for line in lines.strip().split("\n"):
    first,second = line.split('|')

    if first[4:] == second[:-4]:
        print("''[[{}]]''".format(''.join(first[4:])))
    else:
        print(line)

"""
Output:
''[[excellent wheat]]''
''[[brilliant corn|Tom's brilliant corn]]''
''[[spicy chips|spicy fries/chips]]''
"""
,

您可以这样做:

lines="""
''[[excellent wheat|excellent wheat]]''
''[[brillant corn|Tom's brilliant corn]]''
''[[spicy chips|spicy fries/chips]]''
"""

>>> print(re.sub(r'(?<=\[)([^[]*)(?=\|)\|\1(?=\])',r'\1',lines))

''[[excellent wheat]]''
''[[brillant corn|Tom's brilliant corn]]''
''[[spicy chips|spicy fries/chips]]''

Regex Demo


如果您想提高效率 ,可以将simpler regex(无回溯)与一些Python字符串处理结合使用。老实说,我不知道这是不是更快

lines="""
==///Listings==/?
assadsadsadsa
adasdsad
</test>
''[[excellent wheat|excellent wheat]]''
''[[brilliant corn|Tom's brilliant corn]]''
</separation>
Remember to purchase this if on offer
''[[jub|jub/ha]]'',''[[barley|barley/hops]]''
zcxcxzcxz
""".splitlines()

# Python 3.8+ because of the walrus. Break into two line if can't use that
for i,line in enumerate(lines):
    if m:=re.search(r'(?<=\[\[)([^\]\[]*)(?=\]\])',line):
        x=m.group(1).partition('|')
        if x[0]==x[2]:
            span=m.span()
            lines[i]=line[0:span[0]]+x[0]+line[span[1]:]
    
print('\n'.join(lines)) 

打印:

==///Listings==/?
assadsadsadsa
adasdsad
</test>
''[[excellent wheat]]''
''[[brilliant corn|Tom's brilliant corn]]''
</separation>
Remember to purchase this if on offer
''[[jub|jub/ha]]'',''[[barley|barley/hops]]''
zcxcxzcxz