簡體   English   中英

PowerShell 中的可選正則表達式運算符

[英]Optional regular expression operator in PowerShell

在 $string 中,我試圖淘汰第一個“-1”,因此字符串的輸出將是“test test test-Long.xml”。

 $string = 'test test test-1-Long.xml'

 $string -replace '^(.*)-?\d?(-?.*)\.xml$', '$1$2'

我的問題是我需要將相同的第一個“-1”模式設為可選,因為連字符和數字也不能存在。

為什么“ ? ”運算符不起作用? 我也試過{0,1}之后也沒有運氣。

正則表達式是貪婪的,所以引擎無法決定匹配什么,而且是模棱兩可的。

我不確定這是最好的解決方案,但我可以讓它這樣工作:

$string -replace '^([^\-]*)-?\d?(-?.*)\.xml$', '$1$2'

唯一的變化:第一組不能包含破折號:那種“平衡”正則表達式,避免貪婪並產生:

test test test-Long

注意:輸出不是您的答案中要求的test test test-Long.xml 為此,只需刪除xml后綴:

$string -replace '^([^\-]*)-?\d?(-?.*)', '$1$2'

$string -replace '^(.*?)(?:-\\d+)?(-.*?)\\.xml$', '$1$2'如果輸入中的連字符是必需的,則應該可以使用。 $string -replace '^((?:(?!-\\d+).)*)(?:-\\d+)?(.*)\\.xml$', '$1$2'以防輸入可能有沒有連字符。

請參閱正則表達式演示 1正則表達式演示 2

圖案詳情

  • ^ - 字符串的開始
  • (.*?) - 第 1 組盡可能少地捕獲除換行符以外的任何 0+ 個字符(因為*?量詞是惰性的)直到第一個(注意:為了提高正則表達式性能,您可以使用基於緩和的貪婪令牌模式而不是(.*?) - ((?:(?!-\\d+).)*)匹配任何文本,但- + 1 or more digits ,因此,其作用類似於否定字符類,但對於序列符號)
  • (?:-\\d+)? - 貪婪的非捕獲組? 量詞(因此,該組對正則表達式引擎具有更高的優先級,前一個捕獲將在此模式之前結束)捕獲一個連字符,后跟一個或多個數字
  • (-.*?) - 第 3 組捕獲一個強制性的-以及除 LF 之外的任何 0+ 字符,盡可能少
  • \\.xml - 文字文本.xml
  • $ - 字符串的結尾。

為什么是“?” 操作員不工作?

這不是真的。 量詞? 效果很好,因為它匹配量化子模式的一次或次出現。 但是,問題與第一個.*貪婪點匹配子模式結合出現。 查看您的正則表達式:第一個捕獲組抓取整個子字符串直到最后一個.xml ,第二個組為空。 為什么?

由於回溯以及貪婪量詞的工作原理。 .*匹配盡可能多的任何字符,但換行符除外。 因此,它將整個字符串抓取到最后。 然后,回溯開始:一次返回一個字符並針對后續子模式進行測試。

這些是什么? -?\\d?(-?.*) - 它們都可以匹配一個空字符串。 -? 匹配.xml之前的空字符串,好的, \\d? 那里也匹配, -? .*也在那里匹配。

然而, .*再次抓取整個字符串,但有\\.xml模式可以容納。 因此,第二個捕獲組只是空的。 事實上,正則表達式引擎執行的步驟更多(參見正則表達式調試器頁面),但主要思想是這樣的。

暫無
暫無

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

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