簡體   English   中英

在正則表達式中逃避美元符號不起作用

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

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