如何只匹配那些在它们前面有偶数个`%`的数字?

时间:2016-07-10 11:43:43

标签: javascript c++ regex std ecmascript-7

我想捕捉出现在字符串中任何位置的数字,并用"(。+)"替换它们。

但我想只捕捉那些在它们前面有偶数个%的数字。不用担心是否有任何周围的字符被抓住:我们可以使用捕获组过滤掉数字。

我无法提出ECMAscript正则表达式。

这是游乐场:

abcd %1 %%2 %%%3 %%%%4 efgh

abcd%12%%34%%%666%%%%11efgh

成功的捕获将表现如下:
desired behaviour

我尝试过的事情:

attempt 1

attempt 2

attempt 3

如果你意识到,第三次尝试几乎正常。唯一的问题是在操场的第二行。 实际上,我想在那个表达中说的是:

如果数字前面有偶数个% s,则匹配一个数字并且以下任何一个都为真:

  • 上面的整个表达式前面是 nothing [缺少(未使用或其他)字符]。
  • 上面的整个表达式前面是%以外的字符。

有没有办法匹配角色的缺席
这是我在第三次尝试时使用\0尝试做的事情。

3 个答案:

答案 0 :(得分:2)

您可以使用(?:[^%\d]|^|\b(?=%))(?:%%)*(\d+)作为模式,您的号码存储在第一个捕获组中。这也会处理前面带有零%-characters的数字。

这将匹配偶数个%-signs,前提是:

  • 既不是%也不是数字(所以我们不需要在%之前捕获最后一个数字,因为这对于像%%1%%2这样的链不起作用)
  • 字符串的开头
  • 上面提到的链的字边界(因此是任何单词字符)

您可以在行动here

中看到它

答案 1 :(得分:2)

问题

你想要一个带有负无限宽度后瞻性的正则表达式:

(?<=(^|[^%])(?:%%)*)\d+

以下是.NET regex demo

在ES7中,它不受支持,您需要使用特定于语言的方法和简化的正则表达式来匹配数字序列前的任意数量的%/(%*)(\d+)/g然后在{{如果百分号的数量是偶数,则回调1}}并相应地进行。

的JavaScript

您可以只使用JS表示:

,而不是尝试模拟可变宽度的lookbehind

&#13;
&#13;
replace
&#13;
&#13;
&#13;

如果数字前必须至少有2个var re = /(%*)(\d+)/g; // Capture into Group 1 zero or more percentage signs var str = 'abcd %1 %%2 %%%3 %%%%4 efgh<br/><br/>abcd%12%%34%%%666%%%%11efgh'; var res = str.replace(re, function(m, g1, g2) { // Use a callback inside replace return (g1.length % 2 === 0) ? g1 + '(.+)' : m; // If the length of the %s is even }); // Return Group 1 + (.+), else return the whole match document.body.innerHTML = res;,请使用%正则表达式模式,/(%+)(\d+)/g匹配至少1个(或更多)百分号。

转换为C ++

可以在C ++中使用相同的算法。唯一的问题是%+内部没有对回调方法的内置支持。它可以手动添加,并像这样使用:

std::regex_replace

请参阅IDEONE demo

特别感谢回调代码转到John Martin

答案 2 :(得分:0)

我不知道ECMAScript但是以下文档有答案:

ECMAScript regex

搜索否定前瞻,这将产生如下结果:

(?!%)(([%]{2})*\d+)

...其中(?!%)表示前面没有%字面值。