正则表达式用英镑符号替换包裹数字

时间:2013-01-10 21:47:02

标签: php regex

我的文字中有大括号括号{123}{456ABC}。我也有数字没有用括号括起来,即789。我想匹配这些尚未包装的数字并使用PHP的preg_replace用英镑符号#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+)[^\{]

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

这是一个Perl样式的搜索和替换,用于插入#,没有前瞻或后瞻:

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

答案 1 :(得分: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])类似于第一部分,除了查找输入的结尾。

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

    < / LI>