![](/img/trans.png)
[英]How to substitute some part of a text based on a dictionary of patterns and substitute values in python using re.sub?
[英]Python re.sub(): how to substitute all 'u' or 'U's with 'you'
我正在使用python和正则表达式进行一些文本规范化。 我想用'你'替换所有'你'或'你'。 这是我到目前为止所做的:
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'之后出现的角色。 例如,我想要'你!' 被改为'你!'。 任何人都可以告诉我我做错了什么,写正则表达式的最佳方法是什么?
首先,为什么你的解决方案不起作用。 你混淆了很多概念。 主要是与其他人的角色类 。 在第一个字符类中使用|
这源于交替 。 在字符类中,您不需要管道。 只需列出您想要的所有字符(和字符范围):
[Uu]
或者,如果使用不区分大小写的修饰符,只需编写u
即可。 如果在那里编写管道,则字符类实际上将匹配主题字符串中的管道。
现在在第二个字符类中,您可以使用逗号分隔字符,原因有些奇怪。 除了在可匹配的角色中包含逗号外,这也没什么。 s
和W
可能应该是内置的角色类。 然后逃脱他们! 否则,他们将只匹配字面s
和文字W
。 但是\\W
已经包含了你在那里列出的所有内容,所以一个\\W
单独(没有方括号)就足够了。 而最后一部分(^a-zA-Z)
也不起作用,因为它只会将^
, (
, )
和所有字母都包含在字符类中。 否定语法仅适用于整个字符类,如[^a-zA-Z]
。
你真正需要的是断言,有在前面或你之后没有字母u
。 你可以使用lookarounds 。 优点是它们不会包含在比赛中,因此不会被删除:
r'(?<![a-zA-Z])[uU](?![a-zA-Z])'
请注意,我使用了原始字符串。 通常是正则表达式的良好实践,以避免转义序列的问题。
这些都是负面lookarounds是确保没有字母字符之前或之后的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)
取决于您的偏好。
我建议你通过我在这个答案中多次链接的教程来阅读。 这些解释非常全面,应该会让你对正则表达式有一个很好的启发,你可能迟早会再遇到它。
使用特殊字符\\b
,它在单词的开头或结尾处匹配空字符串:
print re.sub(r'\b[uU]\b', 'you', text)
空格不是一个可靠的解决方案,因为还有很多其他标点符号,所以发明了一个抽象字符\\b
来表示一个单词的开头或结尾。
这对我有用:
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,这样我们就不用担心正则表达式中的case了! 顺便说一句,我喜欢伞的时髦拼写! :-)
它也可以通过以下代码实现
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))
我想出的另一个可能的解决方案是:
re.sub(r'([uU]+(.)?\s)',' you ', text)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.