[英]Escaping dollar signs in regex not working
在開始之前,我知道有比正則表達式更好的方法(比如標記化器),這不是問題所在。 我已經堅持使用正則表達式,它已經按照我的需要工作,除了一個特殊情況,這是我需要的建議。
我需要掃描一些類似JavaScript的代碼,並在每個對象聲明前面插入new
關鍵字。 我已經知道需要這個關鍵字的所有對象的名稱了,我知道在我開始之前它們都不會在代碼中有那個關鍵字(所以我不需要處理重復的new
單詞或猜測某些東西是否是對象與否。例如,典型的行可能如下所示:
foo = Bar()
我已經知道Bar
是一個'類',並且需要'new'來進行對象聲明。 以下正則表達式可以解決問題:
for classname in allowed_classes:
line = re.sub(r'^([^\'"]*(?:([\'"])[^\'"]*\2)*[^\'"]*)\b(%s\s*\()' % classname, r'\1new \3', line)
它就像一個魅力,甚至確保當它在一個字符串中時不要觸及classname
(正則表達式的第一部分告訴它確保前面有偶數引號 - 它有點天真,因為它會打破嵌套引號,但我不需要處理這種情況)。 問題是,類名也可以包含$
。 因此,如果allow_classes中存在$Bar
則允許以下行:
foo = $Bar()
由於美元符號,上述正則表達式將忽略它。 我想逃避它會做的伎倆,但這個邏輯似乎對上面的行沒有影響,即使$Bar
是其中一個類:
for classname in allowed_classes:
line = re.sub(r'^([^\'"]*(?:([\'"])[^\'"]*\2)*[^\'"]*)\b(%s\s*\()' % re.escape(classname), r'\1new \3', line)
我也嘗試使用\\
手動逃避它,但它也沒有效果。 有人可以解釋為什么將$
轉換$
\\$
不起作用以及可以解決的問題是什么?
謝謝
你當前的正則表達式不起作用的原因是你的類名前面有一個\\b
。 \\b
將匹配單詞邊界,因此只在單詞字符和非單詞字符之間。 對於字符串foo = Bar()
, \\b
將在空格和B
之間匹配,但是對於foo = $Bar()
, \\b
在空格和$
之間不能匹配,因為它們都是非單詞字符。
要解決此問題,請將\\b
更改為(?=\\b|\\B\\$)
,這是生成的正則表達式:
for classname in allowed_classes:
line = re.sub(r'^([^\'"]*(?:([\'"])[^\'"]*\2)*[^\'"]*)(?=\b|\B\$)(%s\s*\()' % classname, r'\1new \3', line)
通過使用前瞻 ,您可以處理以下兩種情況:
classname
不以$
開頭,所以在嘗試匹配classname
之前我們想要一個單詞邊界,lookahead里面的\\b
處理這個 classname
確實以$
開頭,所以如果下一個字符是我們要匹配的$
。 我使用\\B\\$
所以它只會匹配$
前面的字符不是單詞字符,但這可能是不必要的,因為我不能想到任何有效的JS代碼,那就是這種情況
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.