Python正则表达式分割但将正则表达式匹配的结束部分放回到字符串中?

标签 python regex

我想找到一个正则表达式,它可以将段落(长字符串,无需担心换行符)分解成句子,其简单规则是 {., ?, !} 后跟一个空格,然后大写字母应该是句子的结尾(我意识到这对于现实生活来说不是一个好的规则)。

我有一些东西可以部分工作,但它并不能完全完成工作:

line = 'a b c FFF! D a b a a FFF. gegtat FFF. A'
matchObj = re.split(r'(.*?\sFFF[\.|\?|\!])\s[A-Z]', line)
print (matchObj)

打印

['', 'a b c FFF!', '', ' a b a a FFF. gegtat FFF.', '']

而我想得到:

['a b c FFF!', 'D a b a a FFF. gegtat FFF.']

有两个问题。

  • 为什么结果中有空成员 ('')?

  • 我明白为什么 D 会从分割结果中被删除 - 它是第一次搜索的一部分。如何以不同的方式构建我的搜索,以便将标点符号后面的大写字母放回原处,以便将其包含在下一个句子中?在这种情况下,如何让 D 出现在分割结果的第二个元素中?

我知道我可以通过某种 for 循环来完成此操作,只需剥离第一个结果,添加回大写字母,然后重新执行一遍,但这似乎不太 Pythonic。如果正则表达式不是这里的方法,是否有一些东西仍然可以避免 for 循环?

感谢您的任何建议。

最佳答案

  1. 要解决第一个问题(split()返回的结果中存在空字符串),使用 findall()finditer() :

    >>> re.findall(r'(.*?\sFFF[\.|\?|\!])\s[A-Z]', line)
    ['a b c FFF!', ' a b a a FFF. gegtat FFF.']
    

    您在输出中看到空字符串,因为这就是 split() 应该做的事情:使用匹配的组作为分隔符来分割输入字符串。

  2. 对于第二个问题(输出中缺少D),使用 lookahead assertion (?=...):

    >>> re.findall(r'(.*?\sFFF[\.|\?|\!])\s(?=[A-Z])', line)
    ['a b c FFF!', 'D a b a a FFF. gegtat FFF.']
    

    前瞻、负前瞻、后顾和后顾是四种断言,您可以使用它们来表示“仅当后面/前面有组时才匹配该组,但不消耗字符串”。

  3. 仔细阅读您的表达式,您似乎误解了 [...] 运算符的语法。您似乎想匹配 .?!.

    之一

    如果是这种情况,那么您可以[\.|\?|\!] 重写为 [.?!] :

    >>> re.findall(r'(.*?\sFFF[.?!])\s(?=[A-Z])', line)
    ['a b c FFF!', 'D a b a a FFF. gegtat FFF.']
    

    [.?!] 不仅更紧凑,而且更正确:使用 [\.|\?|\!] 您还可以匹配| 字符(因此 'a b c FFF|' 是有效匹配)!

关于Python正则表达式分割但将正则表达式匹配的结束部分放回到字符串中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30084912/

相关文章:

python - 用枢轴点 Python 拟合曲线

python - 在 Python 中获取当前脚本的名称

python - Pandas 数据框基于列值拆分列表

php - 从字符串中删除值

javascript - 正则表达式不会理解空白

python - mysql插入查询中的转义字符串

python - 查找一系列重复元素的更优雅方式

php - 不以 2 个打开和关闭的大括号开始和结束的字符串的正则表达式

javascript - 如何缩小正则表达式验证失败的原因?

javascript - 正则表达式 jquery 验证器中字符类的范围乱序