替换 <sup> 标签内的所有数字(且仅替换数字)

Replacing all numbers (and only numbers) inside <sup> tags

我在使用正则表达式对整个字符串进行一些替换时遇到了很多问题。

我需要找到并替换 <sup> 标签内的所有数字(并且只有数字),将每个数字包裹在三个大括号内(即 {{{1}}})。它们可以以多种书面形式出现,例如:

<sup>1</sup>
<sup>1, 2</sup>
<sup>1, 2, 3</sup>
<sup>1, 2, 3\-4</sup>
<sup>1, 2, 3- 4</sup>

这些示例的预期结果应该类似于:

<sup>{{{1}}}</sup>
<sup>{{{1}}}, {{{2}}}</sup>
<sup>{{{1}}}, {{{2}}}, {{{3}}}</sup>
<sup>{{{1}}}, {{{2}}}, {{{3}}}\-{{{4}}}</sup>
<sup>{{{1}}}, {{{2}}}, {{{3}}}- {{{4}}}</sup>

遗憾的是,我已经尝试了很多东西,但没有任何效果。一个例子:

#<sup>([^<\d]*)(\d+)([^<]*)</sup>#

它与 <sup>123</sup> 示例一起使用,并将第一个数字匹配到其他示例中,但在第一个之后它不会得到任何东西。

任何帮助 and/or 线索将不胜感激。

提前致谢!

您可以使用此代码:

function sanitizeString($string) {

// matriz de entrada
$what = array('0','1','2','3','4','5','6','7','8','9');

// matriz de saída
$by = array('{{0}}','{{1}}','{{2}}','{{3}}','{{4}}','{{5}}','{{6}}','{{7}}','{{8}}','{{9}}');

// devolver a string
return str_replace($what, $by, $string);
}

echo sanitizeString("hoje é dia 1 testando o 2");

这是不使用正则表达式的最简单方法。

由于不能嵌套 <sup> 标签,看来您可以使用正则表达式来完成此任务。

最简单的方法是匹配所有 <sup> 标签(仅使用 '~<sup>[^<]*</sup>~')并在回调中用您需要的内容替换所有数字块(使用非常简单的 '~\d+~'正则表达式):

$s = '<sup>1, 2, 3- 124</sup>';
echo preg_replace_callback('~<sup>[^<]*</sup>~', function ($m) {
    return preg_replace('~\d+~', '{{{[=10=]}}}', $m[0]);
}, $s);
// => <sup>{{{1}}}, {{{2}}}, {{{3}}}- {{{124}}}</sup>

PHP demo

如果您更喜欢将 1-regex 方法与 preg_replace 一起使用,请使用基于 \G 的正则表达式:

~(?:\G(?!\A)[^\d<]*|<sup>[^\d<]*)\K\d+~

参见regex demo and another PHP demo

$s = '<sup>1, 2, 3- 124</sup> 2345';
echo preg_replace('~(?:\G(?!\A)[^\d<]*|<sup>[^\d<]*)\K\d+~', '{{{[=12=]}}}', $s);
// => <sup>{{{1}}}, {{{2}}}, {{{3}}}- {{{124}}}</sup> 2345

详情:

  • (?:\G(?!\A)[^\d<]*|<sup>[^\d<]*) - 自定义边界,两者之一:
    • \G(?!\A)[^\d<]* - 上一次成功匹配的结尾 (\G(?!\A)),然后是 < 和数字
    • 以外的 0+ 个字符
    • | - 或
    • <sup>[^\d<]* - <sup> 和除 < 和数字
    • 以外的 0+ 个字符
  • \K - 运算符在当前迭代中省略到目前为止匹配的整个文本
  • \d+ - 1+ 位数