51

我正在使用 python 和正则表达式进行一些文本规范化。我想用'you'代替所有'u'或'U'。这是我到目前为止所做的:

import re
text = 'how are u? umberella u! u. U. U@ U# u '
print re.sub (' [u|U][s,.,?,!,W,#,@ (^a-zA-Z)]', ' you ', text)

我得到的输出是:

how are you  you berella you  you  you  you  you  you

如您所见,问题在于“umberella”更改为“berella”。我也想保留出现在“u”之后的字符。例如,我想要“你!” 改为“你!”。谁能告诉我我做错了什么以及编写正则表达式的最佳方法是什么?

4

5 回答 5

72

首先,为什么您的解决方案不起作用。你混淆了很多概念。主要是字符类与其他字符类。在您使用的第一个字符类中,|它源于alternation。在字符类中,您不需要管道。只需列出您想要的所有字符(和字符范围):

[Uu]

u或者,如果您使用不区分大小写的修饰符,则只需编写。如果你在那里写一个管道,字符类实际上会匹配你的主题字符串中的管道。

现在在第二个字符类中,出于某种奇怪的原因,您使用逗号分隔字符。除了在可匹配字符中包含逗号之外,这也无济于事。s并且W可能应该是内置的字符类。然后逃离他们!否则它们只会匹配 literals和 literal W。但是\W已经包含了您在此处列出的所有其他内容,因此\W单独(不带方括号)就足够了。最后一部分(^a-zA-Z)也不起作用,因为它将简单地将^,()所有字母包含到字符类中。否定语法仅适用于整个字符类,例如[^a-zA-Z].

你真正想要的是断言你的 . 前面或后面没有字母u。您可以为此使用环视。优点是它们不会包含在匹配中,因此不会被删除:

r'(?<![a-zA-Z])[uU](?![a-zA-Z])'

请注意,我使用了原始字符串。通常是正则表达式的好习惯,以避免转义序列出现问题。

这些是负面的环顾四周,确保您的 . 之前或之后没有字母字符u。这是断言周围有一个非字母字符(与您所做的类似)的重要区别,因为后一种方法在字符串的开头或结尾不起作用。

当然,您可以you从替换字符串中删除空格。

如果您不想替换u数字旁边的数字,您可以轻松地将数字包含到字符类中:

r'(?<![a-zA-Z0-9])[uU](?![a-zA-Z0-9])'

如果由于某种原因相邻的下划线也会取消您u的替换资格,您也可以将其包括在内。但是字符类与内置的一致\w

r'(?<!\w)[uU](?!\w)'

在这种情况下,这相当于 EarlGray 的r'\b[uU]\b'.

如上所述,您可以通过使用不区分大小写的修饰符来缩短所有这些。以第一个表达式为例:

re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.I)

或者

re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.IGNORECASE)

取决于你的喜好。

我建议您阅读我在此答案中多次链接的教程。这些解释非常全面,应该让您在正则表达式方面有一个良好的开端,您可能迟早会再次遇到。

于 2012-12-06T17:08:20.177 回答
16

使用特殊字符\b,匹配单词开头或结尾的空字符串:

print re.sub(r'\b[uU]\b', 'you', text)

空格不是一个可靠的解决方案,因为还有很多其他标点符号,所以\b发明了一个抽象字符来指示单词的开头或结尾。

于 2012-12-06T17:05:10.577 回答
3

这对我有用:

    import re
    text = 'how are u? umberella u! u. U. U@ U# u '
    rex = re.compile(r'\bu\b', re.IGNORECASE)
    print(rex.sub('you', text))

它预编译正则表达式并使用 re.IGNORECASE,这样我们就不必担心正则表达式中的大小写了!顺便说一句,我喜欢伞的时髦拼写!:-)

于 2018-03-23T08:43:14.167 回答
2

也可以用下面的代码来实现

import re

text = 'how are u? umberella u! u. U. U@ U# u '
print (re.sub (r'[uU] ( [^a-z] )', r' you\1 ', text))

或者

print (re.sub (r'[uU] ( [\s!,.?@#] )', r' you\1 ', text))
于 2018-07-31T14:27:51.660 回答
1

我想出的另一个可能的解决方案是:

re.sub(r'([uU]+(.)?\s)',' you ', text)
于 2017-11-14T14:21:13.157 回答