【问题标题】:Replacing all numbers (and only numbers) inside <sup> tags替换 <sup> 标签内的所有数字(并且只有数字)
【发布时间】:2017-01-19 11:11:11
【问题描述】:

我在让正则表达式工作以在整个字符串中进行一些替换时遇到很多问题。

我需要找到并替换&lt;sup&gt; 标记中的所有数字(并且仅是数字),并将它们中的每一个都包含在三个花括号中(即{{{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>#

它适用于&lt;sup&gt;123&lt;/sup&gt; 示例,并将第一个数字匹配到其他示例中,但在第一个之后它不会得到任何东西。

任何帮助和/或线索将不胜感激。

提前致谢!

【问题讨论】:

  • 好,你有没有尝试过具体的?
  • 可悲的是,我尝试了很多东西,但无济于事。一个示例:#&lt;sup&gt;([^&lt;\d]*)(\d+)([^&lt;]*)&lt;/sup&gt;# 将与 &lt;sup&gt;123&lt;/sup&gt; 示例一起使用,并将第一个数字匹配到其他示例中,但在第一个之后它不会得到任何东西。
  • 那么有一个问题:可以嵌套sup标签吗?

标签: php regex preg-replace


【解决方案1】:

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

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

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

PHP demo

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

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

参见regex demoanother PHP demo

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

详情

  • (?:\G(?!\A)[^\d&lt;]*|&lt;sup&gt;[^\d&lt;]*) - 自定义边界,两者之一:
    • \G(?!\A)[^\d&lt;]* - 上一个成功匹配的结束 (\G(?!\A)),然后是除 &lt; 和数字之外的 0+ 个字符
    • | - 或
    • &lt;sup&gt;[^\d&lt;]* - &lt;sup&gt; 和除 &lt; 和数字之外的 0+ 个字符
  • \K - 运算符忽略当前迭代中匹配的整个文本
  • \d+ - 1 位以上

【讨论】:

  • 抱歉进行了大量编辑,只需确保 \D[^\d&lt;] 以保留标签。
  • 你太棒了,维克托!我欠你一杯[咖啡|啤酒]。非常感谢! :D
  • 你的意思是(coffee|beer) :)。是的,咖啡更好,我不喝酒。
  • 你看到了吗?这就是为什么我没有让它工作,我只是很讨厌正则表达式。大声笑!
【解决方案2】:

您可以使用此代码:

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");

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

【讨论】:

  • 这样,你 1) 不要确保替换只发生在 &lt;sup&gt; 标签内,并且 2) 123 将变成 {{1}}{{2}}{{3}} 而不是 {{123}}
  • 谢谢@WiktorStribiżew,我真的没想到。
猜你喜欢
  • 1970-01-01
  • 2020-10-19
  • 2012-02-08
  • 2011-09-07
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
相关资源
最近更新 更多