【问题标题】:Python/Regex: Split string if a line does contain a certain special characterPython/Regex:如果一行确实包含某个特殊字符,则拆分字符串
【发布时间】:2018-02-23 02:19:33
【问题描述】:

我试图在一个字符上拆分多行字符串,但前提是该行不包含:。不幸的是,我看不到使用re.split() 对字符: 进行负面回溯的简单方法,因为: 可能出现在字符串前面的另一行中。

例如,我想在) 上拆分下面的字符串。

字符串:

Hello1 (
First : (),
Second )

Hello2 (
First 
)

输出:

['Hello1 (\nFirst : (),\nSecond', 'Hello2 (\nFirst \n']

【问题讨论】:

  • 我不确定是否有可能仅使用正则表达式来实现这一点。如果有人提出答案,我会感到惊讶。
  • ( @AmitSingh ) 在某些正则表达式引擎中是可能的,例如在 PowerShell / .Net 中,它适用于$string -split '(?m)(?<=^[^:]+)\)',但 Python 似乎不支持可变长度的后向匹配,这排除了这种方法。我想不出仅使用正则表达式的方法。
  • 我可以使用的一种方法是用换行符\n 分割,然后在行字符串上使用正则表达式lookbehind,但这在我的情况下并不可靠
  • @TessellatingHeckler:在较新的regex 模块中无耻地使用了您的表达方式,但也提供了其他方式。

标签: python regex regex-negation regex-lookarounds


【解决方案1】:

Python 是可能的,尽管原生 re 模块不是“开箱即用”。

第一选择

较新的regex module 支持可变长度的lookbehind,因此您可以使用

(?<=^[^:]+)\)
# pos. lookbehind making sure there's no : in that line


Python:
import regex as re

data = """
Hello1 (
First : (),
Second )

Hello2 (
First 
)"""

pattern = re.compile(r'(?<=^[^:]+)\)', re.MULTILINE)

parts = pattern.split(data)
print(parts)

产量

['\nHello1 (\nFirst : (),\nSecond ', '\n\nHello2 (\nFirst \n', '']


第二种选择

或者,您可以匹配有问题的行,然后让它们以(*SKIP)(*FAIL) 失败:

^[^:\n]*:.*(*SKIP)(*FAIL)|\)
# match lines with at least one : in it
# let them fail
# or match )


再次在Python
pattern2 = re.compile(r'^[^:\n]*:.*(*SKIP)(*FAIL)|\)', re.MULTILINE)
parts2 = pattern.split(data)
print(parts2)

a demo for the latter on regex101.com


第三种选择

好的,现在答案比以前想象的要长。您甚至可以在函数的帮助下使用本机 re 模块来实现。在这里,您需要先替换有问题的),然后用替换符分割:

def replacer(match):
    if match.group(1) is not None:
        return "SUPERMAN"
    else:
        return match.group(0)

pattern3 = re.compile(r'^[^:\n]*:.*|(\))', re.MULTILINE)
data = pattern3.sub(replacer, data)
parts3 = data.split("SUPERMAN")
print(parts3)

【讨论】:

  • 我以前从未见过(*SKIP)(*FAIL),这真的很有趣。
  • @TessellatingHeckler:确实,它仅在特定情况下匹配模式非常强大。
  • @Jan 哇,感谢您对此的不同解决方案。像 TessellatingHeckler 一样,我从未见过 (*SKIP)(*FAIL) 的用法。解决方案 1 不适用于我遇到的更普遍的问题,所以我试图找出原因。但解决方案 2 做到了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
相关资源
最近更新 更多