【问题标题】:Tokenize by using regular expressions (parenthesis)使用正则表达式(括号)进行标记
【发布时间】:2017-08-22 21:49:15
【问题描述】:

我有以下文字:

I don't like to eat Cici's food (it is true)

我需要将其标记为

['i', 'don't', 'like', 'to', 'eat', 'Cici's', 'food', '(', 'it', 'is', 'true', ')']

我发现以下正则表达式 (['()\w]+|\.) 拆分如下:

['i', 'don't', 'like', 'to', 'eat', 'Cici's', 'food', '(it', 'is', 'true)']

如何从令牌中取出括号并使其成为自己的令牌?

感谢您的想法。

【问题讨论】:

  • 您打算拆分或匹配这些令牌吗?将它们与\w+(?:'\w+)?|[^\w\s] 匹配可能更容易。
  • 拆分和匹配有什么区别?总结一下我需要的问题是 (foo) -> ["(", "foo", ")"])
  • 很好,然后使用re.findall(r"\w+(?:'\w+)?|[^\w\s]", s)
  • 对不起,必须使用双引号字符串文字,我编辑了评论。它对字符串进行tokenize。只是测试,你会看到。 w+(?:'\w+)? 将匹配所有 1+ 个单词的字符块,后跟可选的 ',后跟 1+ 个单词的 char 子字符串,[^\w\s] 将匹配除单词和空白字符之外的单个字符。
  • 仅适用于 (foo) - re.findall(r'\w+|\W', s) - 匹配 1 个或多个单词字符 (\w+),或 (|) 1 个非单词字符 (\W)。但是,如果您打算避免匹配空格(可以与\W 匹配),则需要使用[^\w\s] 从模式中排除它们。这是一种有例外的对比原则。我会发布一个答案。

标签: regex string split tokenize


【解决方案1】:

当您想使用对上下文有特殊限制的正则表达式对字符串进行标记时,您可以使用通常产生更清晰输出的匹配方法(尤其是当涉及到结果列表中的空元素时)。

任何单词字符都匹配\w,任何非单词字符匹配\W。如果您想将字符串标记为单词和非单词字符,您可以使用\w+|\W+ 正则表达式。但是,在您的情况下,您希望匹配可选地后跟 ' 后跟 1+ 个单词字符的单词字符块,以及任何其他非空格的单个字符。

使用

re.findall(r"\w+(?:'\w+)?|[^\w\s]", s)

这里,\w+(?:'\w+)? 匹配 peoplepeople's 之类的单词,[^\w\s] 匹配单词和空白字符以外的单个字符。

regex demo

Python demo:

import re
rx = r"\w+(?:'\w+)?|[^\w\s]"
s = "I don't like to eat Cici's food (it is true)"
print(re.findall(rx, s))

另一个将使用() 进行标记的示例:

[^()\s]+|[()]

regex demo

这里,[^()\s]+ 匹配除 () 和空格之外的 1 个或多个符号,[()] 匹配 ()

【讨论】:

    【解决方案2】:

    您应该将单数字符标记(在这种特殊情况下为括号)与表示串联标记的字符分开:

    ([().]|['\w]+)
    

    演示:https://regex101.com/r/RQfYhL/2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多