0

我的文本中包含用大括号括起来的数字,即{123}{456ABC}. 我也有没有用括号括起来的数字,即789. 我想匹配这些尚未包装的数字并使用 PHP 的 preg_replace 将它们用磅符号 ie 包装起来#789#。数字的范围通常为 1-3 位。

print(preg_replace('/\d+/','#$0#',
'1) I can count to 2997510. You can only count to {456ABC}.'));

期望的输出:

#1#) I can count to #2997510#. You can only count to {456ABC}.

什么正则表达式会匹配这些数字?我已经尝试过负前瞻(?![^\{])\d+[^\{](\d+)[^\{]

4

2 回答 2

1

[^\{\dA-F]([A-F\d]+)[^\}\dA-F]

(我假设您正在尝试将十六进制数字与大写字母匹配;如果不是,只需适当地更改字符类。)

额外\d的 's 在负字符类中,因为如果它们不存在,那么引擎将通过切断最外面的数字来避免括号。例如,[^\{](\d+)[^\}]将匹配 {34567} 中的 456。

数字本身是任何匹配的“第 1 组”。如果您需要整个匹配本身作为数字,请使用前瞻和后瞻:

(?<=[^\{\dA-F])([A-F\d]+)(?=[^\}\dA-F])

这是插入#'s 的 Perl 风格的搜索和替换,没有前瞻或后瞻:

s/([^\{\dA-F])([A-F\d]+)([^\}\dA-F])/$1#$2#$3/g

于 2013-01-10T22:11:24.083 回答
0

(\A|[^{\d])(\d[\d\w]*)(\z|[^\}\d\z])应该为你做。

像这样使用:

print(preg_replace('/(\A|[^{\d])(\d[\d\w]*)(\z|[^\}\d\z])/','$1#$2#$3',
'1) I can count to 2997510. You can only count to {456ABC}.'));

解释:

  • 第一部分(\A|[^{\d])匹配输入的开头(以捕获字符串开头的数字)或非{数字或数字。这部分确保数字尚未包装。

  • 第二部分(\d[\d\w]*)进行数字的实际匹配。它匹配任何以数字开头后跟任意数量的连续数字或字母的内容。

  • 最后一部分(\z|[^\}\d\z])类似于第一部分,除了查找输入的结尾。

  • 因为这个正则表达式可以在目标数字之前和之后捕获一个字符,所以使用第一个和第三个匹配的子组重新添加这些字符很重要(如 PHP 示例中所示。

于 2013-01-10T22:24:32.147 回答