簡體   English   中英

正則表達式 (PCRE):以存在字符串為條件匹配所有數字

[英]Regex (PCRE): Match all digits conditional upon presence of a string

使用 PCRE,我只想捕獲一行中的所有數字,但前提是該行中的任何位置都存在某個字符串(例如“STRING99”)。

例如,考慮以下兩種情況:

a1 STRING99 2b c3d

a1 2b c3d

在第一種情況下,我希望結果為“19923”。 在第二種情況下,我想要一個空結果。

我不確定這是可能的。 它可能適用於可變長度的lookbehind,但在PCRE 中不受支持。 此外,像(?=.*STRING99.*$)(\\D|(\\d))*工作,但是“重復的捕獲組將只捕獲最后一次迭代”,這意味着第二個捕獲組只捕獲最后一個數字。 我無法找到解決方法。

(這顯然不難通過 2 個連續的 Regex 操作實現,但我希望在一個公式中實現。)

您可以在preg_replace使用這個 PCRE 正則表達式:

^(?!.*STRING99).*(*SKIP)|\D+

正則表達式演示

正則表達式詳情:

  • ^ : 開始
  • (?!.*STRING99) : Lokahead 檢查輸入中是否有STRING99
  • .*(*SKIP) : 匹配輸入的其余部分直到結束並跳過它
  • | : 或者
  • \\D+ : 匹配 1+ 非數字

PHP代碼:

$repl = preg_replace('~^(?!.*STRING99).*(*SKIP)|\D+~', '', $str);

我們可以使用帶有回調函數的正則表達式替換:

$output = preg_replace_callback('/^.*\bSTRING99\b.*$/', function ($match) {
    return preg_replace("/\D+/", "", $match[0]);
}, 'a1 STRING99 2b c3d');

echo $output;   // prints 1992

這里的方法是首先只匹配包含STRING 99輸入。 然后在這樣的匹配中我們去掉所有非數字字符。 不匹配將不會完成此替換。

您可以使用

(?:\G(?!^)|^(?=.*STRING99)|^.*(*ACCEPT))\d*\K\D+

請參閱正則表達式演示(我將\\D替換為[^\\d\\n]僅用於演示目的,因為測試是針對多行字符串執行的)。

細節

  • (?:\\G(?!^)|^(?=.*STRING99)|^.*(*ACCEPT)) - 前一個成功匹配的結束( \\G(?!^) )或( | )如果在任何 0+ 個字符之后有一個STRING99字符串(參見^(?=.*STRING99) )或(否則)整個字符串與^.*匹配並返回成功匹配(模式不是進一步解析)
  • \\d* - 消耗了 0 位或更多位數字
  • \\K - 並從匹配內存緩沖區中丟棄
  • \\D+ - 1 個或多個非數字字符(最終將被刪除)。

暫無
暫無

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

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