【问题标题】:Regex splits more than once正则表达式多次拆分
【发布时间】:2012-12-28 16:55:14
【问题描述】:

我写了这个正则表达式(在 python 3 中):(?<![\u0410-\u042F])([.!?])(?=(\s)?(\s)?[\u0410-\u042F]|[\u04E8]|["]|[\u201C]|![0-9])

我用python的re.split()

它用西里尔字母分割句子。它们由\n 分隔。所以它应该拆分这个:

Мамлекеттик айыптоочу Биринчи май райондук сотуна берген бул сунушун диний кастыкты ырбатпоо аракети менен негиздеди. Мусулмандарга акаарат келтирип жатат деген кайрылуу каттын негизинде УКМК Тезекбаевге каршы кылмыш ишин козгоп, сотко өткөргөн. Бул ишти бүгүн Биринчи май райондук соту карап бүттү жана өкүм эртең чыгарыларын маалымдады.

分隔句子:

Мамлекеттик айыптоочу Биринчи май райондук сотуна берген бул сунушун диний кастыкты ырбатпоо аракети менен негиздеди.
Мусулмандарга акаарат келтирип жатат деген кайрылуу каттын негизинде УКМК Тезекбаевге каршы кылмыш ишин козгоп, сотко өткөргөн.
Бул ишти бүгүн Биринчи май райондук соту карап бүттү жана өкүм эртең чыгарыларын маалымдады.

但由于某种原因,句号(最后一个字符)换了一行!!除了最后一个。

我看到他们说不要把 "()" 放在 [.!?] 周围,但如果我这样做了,那么标点符号就会被删除。

【问题讨论】:

  • 大概你也在单独打印结果列表中的每个元素,或者你正在使用'\n'.join(),对吗?

标签: python regex python-3.x


【解决方案1】:

最简单的方法是将捕获的标点重新附加到列表中的前一个元素上:

example = 'Мамлекеттик айыптоочу Биринчи май райондук сотуна берген бул сунушун диний кастыкты ырбатпоо аракети менен негиздеди. Мусулмандарга акаарат келтирип жатат деген кайрылуу каттын негизинде УКМК Тезекбаевге каршы кылмыш ишин козгоп, сотко өткөргөн. Бул ишти бүгүн Биринчи май райондук соту карап бүттү жана өкүм эртең чыгарыларын маалымдады.'

def reattach(sentences):
    punctuation = ('.', '!', '?')
    previous = ''
    for sentence in sentences:
        if sentence not in punctuation:
            previous = sentence
        else:
            yield previous + sentence
            previous = ''
    if previous:
        yield previous

punctuation = re.compile('(?<![\u0410-\u042F])([.!?])(?=(\s)?(\s)?[\u0410-\u042F]|[\u04E8]|["]|[\u201C]|![0-9])')
for sentence in reattach(punctuation.split(example)):
    print(sentence)

在您的示例输入上运行该方法给了我:

Мамлекеттик айыптоочу Биринчи май райондук сотуна берген бул сунушун диний кастыкты ырбатпоо аракети менен негиздеди.
 Мусулмандарга акаарат келтирип жатат деген кайрылуу каттын негизинде УКМК Тезекбаевге каршы кылмыш ишин козгоп, сотко өткөргөн.
 Бул ишти бүгүн Биринчи май райондук соту карап бүттү жана өкүм эртең чыгарыларын маалымдады.

【讨论】:

  • 这里有错误:for sentence in reattach(punctuation.split(input)): TypeError: expected string or buffer
  • 另外,为什么 re.compile() 而不是 re.split() ?
  • 在您的情况下input 是什么?我用 Python 3.3 对此进行了测试,其中inputstr。显式的compile 可以让事情变得更快一点,否则它与使用re.split() 没有什么不同。
  • @user1925847:我已在答案中将变量 input 重命名为 example,以避免与内置函数 input() 发生意外混淆。
  • @user1925847:有趣的是,python 3.2 及更早版本在我用来定义正则表达式模式的r'' 原始字符串方面存在问题。删除 r 使事情在早期的 python 版本中工作。 :-)
猜你喜欢
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2013-08-11
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多