[英]Can I use re.sub (or regexobject.sub) to replace text in a subgroup?
我需要解析一個看起來像這樣的配置文件(簡化):
<config>
<links>
<link name="Link1" id="1">
<encapsulation>
<mode>ipsec</mode>
</encapsulation>
</link>
<link name="Link2" id="2">
<encapsulation>
<mode>udp</mode>
</encapsulation>
</link>
</links>
我的目標是能夠更改特定於特定鏈接的參數,但是我很難讓替換正常工作。 我有一個正則表達式可以隔離特定鏈接上的參數值,該值包含在捕獲組1中:
link_id = r'id="1"'
parameter = 'mode'
link_regex = '<link [\w\W]+ %s>[\w\W]*[\w\W]*<%s>([\w\W]*)</%s>[\w\W]*</link>' \
% (link_id, parameter, parameter)
從而,
print re.search(final_regex, f_read).group(1)
打印ipsec
regex howto中的所有示例似乎都假設一個人想要在替換中使用捕獲組,但是我需要做的是替換捕獲組本身(例如,將Link1模式從ipsec更改為udp)。
我必須給你一個強制性:“不要使用正則表達式來做到這一點。”
查看使用BeautifulSoup做到這一點有多么容易,例如:
>>> from BeautifulSoup import BeautifulStoneSoup
>>> html = """
... <config>
... <links>
... <link name="Link1" id="1">
... <encapsulation>
... <mode>ipsec</mode>
... </encapsulation>
... </link>
... <link name="Link2" id="2">
... <encapsulation>
... <mode>udp</mode>
... </encapsulation>
... </link>
... </links>
... </config>
... """
>>> soup = BeautifulStoneSoup(html)
>>> soup.find('link', id=1)
<link name="Link1" id="1">
<encapsulation>
<mode>ipsec</mode>
</encapsulation>
</link>
>>> soup.find('link', id=1).mode.contents[0].replaceWith('whatever')
>>> soup.find('link', id=1)
<link name="Link1" id="1">
<encapsulation>
<mode>whatever</mode>
</encapsulation>
</link>
查看您的正則表達式,我無法真正確定這是否正是您要執行的操作,但是無論您要執行什么操作,使用BeautifulSoup之類的庫都比嘗試將正則表達式拼湊在一起要好得多。 如果可能,我強烈建議您走這條路線。
這看起來像有效的XML,在這種情況下,您不需要BeautifulSoup,也絕對不需要正則表達式,只需使用任何好的XML庫加載XML,對其進行編輯並打印出來,這是使用ElementTree的一種方法:
import xml.etree.cElementTree as ET
s = """<config>
<links>
<link name="Link1" id="1">
<encapsulation>
<mode>ipsec</mode>
</encapsulation>
</link>
<link name="Link2" id="2">
<encapsulation>
<mode>udp</mode>
</encapsulation>
</link>
</links>
</config>
"""
configElement = ET.fromstring(s)
for modeElement in configElement.findall("*/*/*/mode"):
modeElement.text = "udp"
print ET.tostring(configElement)
它將所有模式元素更改為udp
,這是輸出:
<config>
<links>
<link id="1" name="Link1">
<encapsulation>
<mode>udp</mode>
</encapsulation>
</link>
<link id="2" name="Link2">
<encapsulation>
<mode>udp</mode>
</encapsulation>
</link>
</links>
</config>
假設您的link_regex是正確的,則可以這樣添加括號:
(<link [\w\W]+ %s>[\w\W]*[\w\W]*<%s>)([\w\W]*)(</%s>[\w\W]*</link>)
然后您可以執行以下操作:
p = re.compile(link_regex)
replacement = 'foo'
print p.sub(r'\g<1>' + replacement + r'\g<3>' , f_read)
不知道我會那樣做,但是最快的方法是轉移捕獲:
([\\ w \\ W] [\\ w \\ W] <%s>)[\\ w \\ W] ([\\ w \\ W] )'並替換為group1 + mode + group2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.