【问题标题】:Python regex split but put end part of regex match back into string?Python正则表达式拆分但将正则表达式匹配的结尾部分放回字符串?
【发布时间】:2015-05-06 18:35:17
【问题描述】:

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

我有一些部分工作,但它并没有完全完成工作:

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 循环来完成此操作,只需剥离第一个结果,添加回大写字母,然后重新执行此操作,但这似乎不是 Python 式的。如果正则表达式不是这里的方法,还有什么东西可以避免 for 循环吗?

感谢您的任何建议。

【问题讨论】:

    标签: python regex


    【解决方案1】:
    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.']
      

      Lookaheads、negative lookaheads、lookbehinds 和negative lookbehinds 是四种断言,您可以使用它们来表示“仅在组之后/之前匹配此组,但不使用字符串”。

    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|' 是有效匹配)!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2012-02-09
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多