【问题标题】:How to replace substring that's not enclosed in tags with regex in python如何在python中用正则表达式替换未包含在标签中的子字符串
【发布时间】:2025-11-29 15:20:03
【问题描述】:

我有句子。

text="The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. Obama was reelected president in November 2012".

我想把<PERSON></PERSON>标签放在“奥巴马”中,结果会是这样的:
The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. <PERSON>Obama</PERSON> was reelected president in November 2012".

我想找到子字符串(例如:奥巴马)子字符串之前没有标签<PERSON>,子字符串之后没有标签</PERSON>,但我不知道python中正则表达式的正确语法。
**我是 python 新手:''

使用简单的正则表达式re.sub(namedEntity, "<PERSON>"+namedEntity+"</PERSON>", text) 将给出输出
The president of America is <PERSON>Barack <PERSON>Obama</PERSON></PERSON>. He was born on August 4, 1961. <PERSON>Obama</PERSON> was reelected president in November 2012".

这是我的代码(使用 python2.7)

import re

result=re.sub(r"((?!<PERSON>).*"+namedEntity+".*(?!</PERSON>))","<PERSON>"+namedEntity+"</PERSON>",text)

print "result: "+result

输出
result: &lt;PERSON&gt;Obama&lt;/PERSON&gt;
我不知道这是第一个“奥巴马”还是第二个。

感谢您之前的帮助

【问题讨论】:

  • 您是否从某个地方复制了代码?你明白你在那个正则表达式中做了什么吗?
  • 我在regex101.com/#python 中尝试了正则表达式,从这个答案*.com/questions/6259443/… 中学习。也许我错了,因为我认为 ?!regex 的意思是“不包含正则表达式”:''

标签: python regex substring


【解决方案1】:

你很亲密。在您的新正则表达式r"((?!&lt;PERSON&gt;).*"+namedEntity+".*(?!&lt;/PERSON&gt;))" 中,您有.* 之前和之后匹配'Obama' 和它之前和之后的任何字符并且环视被忽略,因为标签在匹配的组中。如果你删除它们,你会得到你想要的结果。

>>> import re
>>> text = "The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. Obama was reelected president in November 2012"
>>> namedEntity = 'Obama'
>>> result = re.sub(r"((?!<PERSON>)"+namedEntity+"(?!</PERSON>))","<PERSON>"+namedEntity+"</PERSON>",text)
>>> print result
'The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. <PERSON>Obama</PERSON> was reelected president in November 2012'

对于未来的正则表达式测试,regex101 可以很好地检查您实时更改它们时的工作方式。对于您的情况,this 显示正在发生的事情。

【讨论】:

  • 不应该是(?&lt;!&lt;PERSON&gt;)negative lookbehind 吗?我实际上在那里感到困惑。
  • @noob,我不这么认为。您想忽略周围已经有标签的匹配项。
  • 只是一个额外的ideone.com demo 表明这是正确的答案 (+1)。
  • 是吗?!和?巴拉克奥巴马AAA person>。他出生于1961年8月4日。奥巴马AAA于2012年11月在裁员总统“。它给出了结果“美国总统是巴拉克奥巴马人> AAA 人>。他出生于1961年8月4日。奥巴马人> AAA被裁员总统2012 年 11 月”抄送@Holloway
  • @KhusnaNadia,没错,它依赖于名称周围的标签。
【解决方案2】:

只需删除您的正则表达式外观中的.* 部分。

>>>text="The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. Obama was reelected president in November 2012"
>>> surname=re.search(r'<PERSON>(.*)</PERSON>', text).group(1).split()[1]
>>> print surname
Obama
>>> re.sub(r'(?<!<PERSON>)'+surname+'(?!</PERSON>)', '<PERSON>'+surname+'</PERSON>', text)'  
The president of America is <PERSON>Barack Obama</PERSON>. He was born on August 4, 1961. <PERSON>Obama</PERSON> was reelected president in November 2012'
>>> 

注意:您还可以使用正则表达式提取人的姓氏并捕获我在surname 变量中捕获的组。您可以使用(?&lt;!regex) 断言否定的lookbehind 和(?!regex) 断言否定的lookahead

【讨论】:

    最近更新 更多