使用python正则表达式进行单词标记化

时间:2011-06-01 14:09:45

标签: python regex string tags

我正在尝试将字符串拆分为python中的“标签”列表。拆分应该处理诸如“HappyBirthday”之类的字符串并删除大多数标点符号但保留连字符和撇号。我的出发点是:

tags = re.findall("([A-Z]{2,}(?=[A-Z]|$)|[A-Z][a-z]*)|\w+-\w+|[\w']+"

我想转换此示例数据:

Jeff's dog is un-American SomeTimes! BUT NOTAlways

分为:

['Jeff's', 'dog', 'is', 'un-American', 'Some', 'Times', 'BUT', 'NOT', 'Always']

P.S。对不起,我的描述不是很好。我不确定如何解释它,并且大多数谷歌都没有成功。我希望这个例子能够恰当地说明它。

编辑:我认为我需要更精确,所以,

  1. 如果这个词被夸大和资本,就像'联合国美国'一样,它会把它保持为一个单词,那么输出将是'联合国美国'
  2. 如果连字符在任一侧或两侧都有空格,则a''这是'或'这是 - 是'它应该忽略这个并且产生[“这个”,“是”]和[“这个”, “是”,尊重,
  3. 并且如果它位于像“What'sItCalled”之类的单词的中间,它应该产生[“What's”,“It”,“Called”]

2 个答案:

答案 0 :(得分:22)

我建议如下:

re.findall("[A-Z]{2,}(?![a-z])|[A-Z][a-z]+(?=[A-Z])|[\'\w\-]+",s)

这样可以得到你的例子:

["Jeff's", 'dog', 'is', 'un-American', 'Some', 'Times', 'BUT', 'NOT', 'Always']

说明:RegExp由3个备选方案组成:

  1. [A-Z]{2,}(?![a-z])匹配所有字母大写的字词
  2. [A-Z][a-z]+(?=[A-Z])匹配带有第一个captitel字母的字词。前瞻(?=[A-Z])在下一个大写字母
  3. 之前停止匹配
  4. [\'\w\-]+匹配所有其他内容,即可能包含'-的字词。

答案 1 :(得分:1)

为了处理您编辑的案例,我会修改phynfo(+1)很好的答案

>>> s = """Jeff's UN-American Un-American un-American 
           SomeTimes! BUT NOTAlways This- THIS- 
           What'sItCalled someTimes"""
>>> re.findall("[A-Z\-\']{2,}(?![a-z])|[A-Z\-\'][a-z\-\']+(?=[A-Z])|[\'\w\-]+",s)
["Jeff's", 'UN-', 'American', 'Un-', 'American', 'un-American', 
 'Some', 'Times', 'BUT', 'NOT', 'Always', 'This-', 'THIS-', 
 "What's", 'It', 'Called' 'someTimes']

您必须明确定义所需行为的规则。标记化不是一个定义,你必须有类似于phynfo规则的东西。例如,您有'NOTAlways'应该转到'NOT''Always'的规则,并且应该保留连字符。因此,'UN-American'被分开,就像美国联邦分裂一样。您可以尝试定义其他规则,但必须明确规则重叠时应用的规则。