繁体   English   中英

结合三个正则表达式

[英]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

你可以使用分组和管道:

re.sub(r'(\s?\(\w+\))|(s?(Jr.|Sr.))|(".+"\s?)', '', name)

演示

如果你想获得一个有效的(并且大部分时间都在工作)模式,简单地用管道分离你的模式是一个坏主意。 你必须重新考虑你想对你的模式做什么,并从头开始重写它。

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+ba+ ,如果你写a+|a+b所有前面带有ab将永远不会匹配,因为第一个分支之前成功。 但是对于你的例子,没有这种问题。

顺便说一句,如果你知道其中一个分支机构有更多机会成功,那就把它放在交替的第一个位置。

你知道搜索到的子字符串以这些字符之一开头: "(js 。在这种情况下,为什么不用["(js]开始模式,避免测试字符串中所有位置的模式的每个分支。然后,由于已经消耗了第一个字符,因此您只需要使用lookbehind检查每个分支中哪些字符匹配。

通过这些小改进,您可以获得更快的模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM