簡體   English   中英

re.sub無法執行-即使找到了正則表達式模式?

[英]re.sub fails to execute - even if the regex pattern is found?

考慮一下我在Python 2.7上運行過的示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

tstr = r'''    <div class="thebibliography">
   <p class="bibitem" ><span class="biblabel">
 [1]<span class="bibsp">   </span></span><a
 id="Xtester"></a><span
class="cmcsc-10">A<span
class="small-caps">k</span><span
class="small-caps">e</span><span
class="small-caps">g</span><span
class="small-caps">c</span><span
class="small-caps">t</span><span
class="small-caps">o</span><span
class="small-caps">r</span>,</span>
   <span
class="cmcsc-10">P. D.</span><span
class="cmcsc-10"> H.  </span> testöng ... .  <span
class="cmti-10">Draftin:</span>
   <a
href="http://www.example.com/test.html" class="url" ><span
class="cmitt-10">http://www.example.com/test.html</span></a> (2001).
</p>
   </div>

'''

# remove <a id>
tout2 = re.sub(r'''<a[\s]*?id=['"].*?['"][\s]*?></a>''', " ", tstr, re.DOTALL)
# remove class= in <a
regstr = r'''(<a.*?)(class=['"].*?['"])([\s]*>)'''
print(  re.findall(regstr, tout2, re.DOTALL))             # finds
print("------") #
print(      re.sub(regstr, "AAAAAAA", tout2, re.DOTALL )) # does nothing?

當我運行此命令時-第一個正則表達式已按預期替換/替換(消失了); 然后在輸出中我得到:

[('<a\nhref="http://www.example.com/test.html" ', 'class="url"', ' >')]

...這意味着第二個正則表達式正確編寫了(找到了所有三個部分)-但是,當我嘗試將所有代碼段替換為“ AAAAAAA”時-輸出的那部分沒有任何反應:

------
    <div class="thebibliography">
   <p class="bibitem" ><span class="biblabel">
 [1]<span class="bibsp">   </span></span> <span
class="cmcsc-10">A<span
class="small-caps">k</span><span
class="small-caps">e</span><span
class="small-caps">g</span><span
class="small-caps">c</span><span
class="small-caps">t</span><span
class="small-caps">o</span><span
class="small-caps">r</span>,</span>
   <span
class="cmcsc-10">P. D.</span><span
class="cmcsc-10"> H.  </span> testöng ... .  <span
class="cmti-10">Draftin:</span>
   <a
href="http://www.example.com/test.html" class="url" ><span
class="cmitt-10">http://www.example.com/test.html</span></a> (2001).
</p>
   </div>

顯然,正如我期望的那樣,這里沒有“ AAAAAAA”。

問題是什么,我應該怎么做才能讓sub替換顯然已找到的匹配項?

為什么不使用HTML解析器來解析和修改HTML

例如,使用BeautifulSoupreplace_with()

from bs4 import BeautifulSoup

data = """Your html here"""
soup = BeautifulSoup(data)

for link in soup('a', id=True):
    link.replace_with('AAAAAA')

print(soup.prettify())

這會將所有具有id屬性的鏈接替換為AAAAAA文本:

<div class="thebibliography">
<p class="bibitem">
<span class="biblabel">
 [1]
 <span class="bibsp">
 </span>
</span>
AAAAAA
<span class="cmcsc-10">
...

另請參閱:

由於誤用了re.sub方法,因此無法進行替換。如果您查看文檔,請執行以下操作:

re.sub(pattern, repl, string, count=0, flags=0)

但是在代碼中,您將“標志”放在“計數”位置。 這就是為什么re.DOTALL標志被忽略,原因是它位於錯誤的位置。

由於您不需要使用count參數,因此可以刪除re.DOTALL標志並使用內聯修飾符:

regstr = r'''(?s)(<a.*?)(class=['"].*?['"])([\s]*>)'''

但是,使用bs4之類的東西可能更方便。 (如您在@alecxe答案中所見)。

這很簡單:Python標准庫參考說語法或re.sub是: re.sub(pattern, repl, string, count=0, flags=0) 因此,您的最后一個子實際上是(如re.DOTALL == 16):

re.sub(regstr, "AAAAAAA", tout2, count = 16, flags = 0 )

當您需要時:

re.sub(regstr, "AAAAAAA", tout2, flags = re.DOTALL )

最后一個子效果很好...

問題是-您的論點錯了

Python 2.7來源:

def re.sub(pattern, repl, string, count=0, flags=0):
     //code

在這里,您的參數re.DOTALL被視為count參數。

FIX:使用re.sub(regstr, "AAAAAAA", tout2, flags=re.DOTALL )代替

注意:如果您嘗試將編譯與正則表達式一起使用,則sub可以正常工作。

好吧,在這種情況下,顯然,我應該使用一個已編譯的regex對象(而不是直接通過re.模塊調用),並且一切似乎都可以工作(甚至可以使用反向引用)-但我仍然不明白為什么這個問題發生了嗎? 了解最終為什么會很好...無論如何,這是經過更正的代碼段:

# remove <a id>
tout2 = re.sub(r'''<a[\s]*?id=['"].*?['"][\s]*?></a>''', " ", tstr, re.DOTALL)
# remove class= in <a
regstr = r'''(<a.*?)(class=['"].*?['"])([\s]*>)'''
pat = re.compile(regstr, re.DOTALL)
#~ print(  re.findall(regstr, tout2, re.DOTALL))             # finds
print(  pat.findall(tout2))             # finds
print("------") #
# re.purge() # no need
print(      pat.sub(r'\1AAAAAAA\3', tout2, re.DOTALL )) # does nothing?

...這是輸出:

[('<a\nhref="http://www.example.com/test.html" ', 'class="url"', ' >')]
------
    <div class="thebibliography">
   <p class="bibitem" ><span class="biblabel">
 [1]<span class="bibsp">   </span></span> <span
class="cmcsc-10">A<span
class="small-caps">k</span><span
class="small-caps">e</span><span
class="small-caps">g</span><span
class="small-caps">c</span><span
class="small-caps">t</span><span
class="small-caps">o</span><span
class="small-caps">r</span>,</span>
   <span
class="cmcsc-10">P. D.</span><span
class="cmcsc-10"> H.  </span> testöng ... .  <span
class="cmti-10">Draftin:</span>
   <a
href="http://www.example.com/test.html" AAAAAAA ><span
class="cmitt-10">http://www.example.com/test.html</span></a> (2001).
</p>
   </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM