[英]Combine three regular expressions
有没有办法将以下三个表达式合并为一个正则表达式?
name = re.sub(r'\s?\(\w+\)', '',name) # John Smith (ii) --> John Smith
name = re.sub(r'\s?(Jr.|Sr.)$','', name, flags=re.I) # John Jr. --> John
name = re.sub(r'".+"\s?', '', name) # Dwayne "The Rock" Johnson --> Dwayne Johnson
如果你想获得一个有效的(并且大部分时间都在工作)模式,简单地用管道分离你的模式是一个坏主意。 你必须重新考虑你想对你的模式做什么,并从头开始重写它。
p = re.compile(r'["(js](?:(?<=\b[js])r\.|(?<=\()\w+\)|(?<=")[^"]*")\s*', re.I)
text = p.sub('', text).rstrip()
这是对您之前撰写的内容持批评态度的好机会:
\\s?
开始一个模式\\s?
很慢,因为字符串中的每个位置都必须使用和不使用此字符进行测试。 因此,最好在末尾捕获可选的空格并在之后修剪字符串。 (在所有情况下,即使你决定在开始时捕获可选的空格,你也需要修剪结果) "[^"]*"
(注意:这可以改进以处理引号内的转义引号) Jr.
和Sr.
的模式也是假的,以匹配文字.
你需要逃脱它。 除此之外,该模式太不精确,因为它不会检查之前是否还有其他单词字符。 它将匹配例如以“USSR”结尾的句子。 或任何包含“jr”的子串。 或“sr。”。 (要完全严谨,你必须检查之前是否有空格或字符串的开头,但一个简单的单词边界应该足够大部分时间) 现在如何建立你的交替:
顺序可能很重要,特别是如果子模式不是mutualy排他性的。 例如,如果你有子模式a+b
和a+
,如果你写a+|a+b
所有前面带有a
的b
将永远不会匹配,因为第一个分支之前成功。 但是对于你的例子,没有这种问题。
顺便说一句,如果你知道其中一个分支机构有更多机会成功,那就把它放在交替的第一个位置。
你知道搜索到的子字符串以这些字符之一开头: "
, (
, j
, s
。在这种情况下,为什么不用["(js]
开始模式,避免测试字符串中所有位置的模式的每个分支。然后,由于已经消耗了第一个字符,因此您只需要使用lookbehind检查每个分支中哪些字符匹配。
通过这些小改进,您可以获得更快的模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.