php - preg_replace 除匹配字符串外的非匹配字符

php - preg_replace non-matched characters except matched strings

我有这样的字符串:

// example
$str1 = "     10.503 GB  3.4 GiB   ";
$str2 = "  40.29 KiB    ";
$str3 = "14.3 GB    2.1 51   ";

这是我的正则表达式,分别匹配字符串“10.503 GB”、“3.4 GiB”、“40.29 KiB”和“14.3 GB”

$regex = '/(\d+\.\d+ [A-Za-z]+[^\s])/';
preg_match_all($regex, $str1, $out1);
preg_match_all($regex, $str2, $out2);
preg_match_all($regex, $str3, $out3);

所以问题是,如何用用户定义的字符替换与我的正则表达式模式不匹配的非匹配字符?示例如下:

$char = 'A'; // assume this is user input
$str1 = "     10.503 GB  3.4 GiB   ";
$str2 = "  40.29 KiB    ";
$str3 = "14.3 GB    2.1 51   ";

/* preg_replace (or another preg_* magic here */

所以最后的字符串将是

$str1 = "AAAAA10.503 GBAA3.4 GiBAAA";
$str2 = "AA40.29 KiBAAAA";
$str3 = "14.3 GBAAAAAAAAAAAAA";

我知道不使用 preg_replace 的解决方案,但只是假装这里需要 preg_replace(或者如果您愿意,可以使用另一个 preg_*)

所以有可能吗?如果是,我该如何实现?

类似于:

~\d+\.\d+ [a-zA-Z]+\b(*SKIP)(*F)|.~

用 A 代替。

demo

(*SKIP) 强制在模式失败后不重试先前匹配的位置。 (*F)(*FAIL) 强制模式失败。

请注意,要处理没有小数的值,您应该将 \d+\.\d+ 替换为 \d+(?:\.\d+)?


如果您不使用带有这些回溯控制动词的正则表达式引擎(仅适用于 Perl、使用 PCRE 的语言或新的 Python 正则表达式模块),您可以通过捕获实现相同的效果组和反向引用:

pattern: ((?:\d+(?:\.\d+)? [a-zA-Z]+\b)*).
replacement: A
or: A

使用 PCRE、Perl、Python 正则表达式模块和 Ruby 2,您也可以这样做:

pattern: (?:\d+(?:\.\d+)? [a-zA-Z]+\b)*\K.
replacement: A