Regex 正则表达式(PCRE):根据字符串的存在匹配所有数字

Regex 正则表达式(PCRE):根据字符串的存在匹配所有数字,regex,pcre,Regex,Pcre,使用PCRE,我只想捕获一行中的所有数字,但仅当某个字符串(如“STRING99”)存在于该行中的任何位置时 例如,考虑这两种情况: a1 STRING99 2b c3d a1 2b c3d 在第一种情况下,我希望结果是“19923”。 在第二种情况下,我想要一个空结果 我不确定这是否可能。它可能适用于可变长度的查找,但PCRE中不支持此功能。此外,类似于(?=.*STRING99.*$)(\D |(\D))*的方法也可以,但“重复捕获组只捕获最后一次迭代”,这意味着第二个捕获组只捕获最后一

使用PCRE,我只想捕获一行中的所有数字,但仅当某个字符串(如“STRING99”)存在于该行中的任何位置时

例如,考虑这两种情况:

a1 STRING99 2b c3d

a1 2b c3d
在第一种情况下,我希望结果是“19923”。 在第二种情况下,我想要一个空结果

我不确定这是否可能。它可能适用于可变长度的查找,但PCRE中不支持此功能。此外,类似于
(?=.*STRING99.*$)(\D |(\D))*
的方法也可以,但“重复捕获组只捕获最后一次迭代”,这意味着第二个捕获组只捕获最后一个数字。我无法找到解决此问题的方法


(这显然不难用两个连续的正则表达式操作来实现,但我希望用一个公式来实现。)

我们可以使用带有回调函数的正则表达式替换:

$output=preg\u replace\u回调('/^.*\bSTRING99\b.*$/',函数($match){
返回preg_replace(“/\D+/”,“”,$match[0]);
}“a1 STRING99 2b c3d”);
echo$output;//印刷品1992
这里的方法是首先只匹配包含
字符串99
的输入。然后在这种匹配上,我们去掉所有非数字字符。非匹配项不会进行此替换。

您可以使用

(?:\G(?!^)|^(?=.*STRING99)|^.*(*ACCEPT))\d*\K\d+
请参阅(其中我将
\D
替换为
[^\D\n]
,仅用于演示目的,因为测试是针对多行字符串执行的)

详细信息

  • (?:\G(?!^)|^(?=.*STRING99)| ^.*(*ACCEPT))
    -上一次成功匹配的结束(
    \G(?!^)
    )或(
    |
    )字符串开始位置(如果在任何0+字符之后有
    STRING99
    字符串(请参见
    ^(?.*STRING99)
    )或(其他)整个字符串与
    ^.*
    匹配,并返回成功的匹配(不进一步分析模式)
  • \d*
    -消耗了0个或更多数字
  • \K
    -并从匹配内存缓冲区中丢弃
  • \D+
    -1个或多个非数字字符(最终将被删除)

您可以在
preg\u replace
中使用此PCRE正则表达式:

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

正则表达式详细信息:

$repl = preg_replace('~^(?!.*STRING99).*(*SKIP)|\D+~', '', $str);
  • ^
    :开始
  • (?!*STRING99)
    :Lokahead检查输入中是否有
    STRING99
  • *(*跳过)
    :匹配输入的其余部分,直到结束并跳过它
  • |
    :或
  • \D+
    :匹配1+非数字
PHP代码:

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

这是一个优雅的解决方案。此外,
(*跳过)
将被省略。谢谢!这个解决方案似乎也很好。@Logitope很高兴它对您有效。另外,如果我的回答对您有帮助(请参阅),因为您在达到15个代表点后有权享有向上投票的特权。请注意,您可能会对所有有帮助的答案进行投票。我无法尝试此方法,因为我实际上不是在PHP中工作,而是在Autohotkey中使用PCRE。不过,感谢您提供这种替代方法。