查找包含转义分隔符(Regexp)形式的子字符串

时间:2019-01-02 12:11:06

标签: javascript regex

大家好!

我正在玩降价游戏,处理行内标记和转义字符。

问题:

我要对此进行转换:some text *some number \* other number* more text

对此:some text <strong>some number * other number</strong> more text

我当前的模式是:/((?!\\)\*)(.*?)((?!\\)\*)/g

但是(.*?)组似乎捕获了\字符,因此第三组找到了第二个*字符并停止寻找应该作为其目标的第三个字符。 / p>

可能的解决方案:

我可以使用负向后看法/((?<!\\)\*)(.*?)((?<!\\)\*)/g解决此问题,但我想避免出现这种情况。

我可以修改其他模式以使其起作用吗?

3 个答案:

答案 0 :(得分:2)

您可以使用

var str = "some text *some number \\* other number* more text";
console.log(
 str.replace(/((?:^|[^\\])(?:\\{2})*)\*([^\\*]*(?:\\[\s\S][^*\\]*)*)\*/g, 
   function($0, $1, $2) { return $1 + '<strong>' + $2.replace(/\\([\s\S])/g, '$1') + '</strong>'; }
 )
)

第一个/((?:^|[^\\])(?:\\{2})*)\*([^\\*]*(?:\\[\s\S][^*\\]*)*)\*/g正则表达式匹配未转义的*中的所有字符串:

  • ((?:^|[^\\])(?:\\{2})*)-第1组:
    • (?:^|[^\\])-字符串的开头或非反斜杠
    • (?:\\{2})*-任何0+出现双反斜杠(这避免了与转义的*匹配)
  • \*-一个*字符
  • ([^\\*]*(?:\\[\s\S][^*\\]*)*)-第2组:
    • [^\\*]*-除\*以外的0多个字符
    • (?:\\[\s\S][^*\\]*)*-0个以上的序列
      • \\[\s\S]-一个\和任何字符
      • [^*\\]*-除\*以外的0多个字符
  • \*-一个*字符。

将匹配项作为replace方法的第二个参数传递给匿名方法,并且处理组2的内容以使用.replace(/\\([\s\S])/g, '$1')\\“取消转义”任何转义序列。匹配一个反斜杠,([\s\S])匹配并将任何字符捕获到组1中,这就是用组占位符$1替换后剩下的内容。

答案 1 :(得分:1)

您可以使用

\*(.*)\*

这使用上面的正则表达式来查找*,直到最后一个*。而且比起\\(.),我要找到转义字符,并用捕获的组替换它。

const regex = /\*(.*)\*/gm;
const str = `some text *some number \\* other number* more text`;
const subst = `<strong>$1</strong>`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
const finalResult = result.replace(/\\(.)/,'$1')   //replacing escaped character here

console.log(finalResult);

更新:用于匹配多个子字符串

const regex = /\*(.*?[^\\])\*/gm;
const str = `some text *some number \\* other number* blah blah *some number \\* other number* more text`;
const subst = `<strong>$1</strong>`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
const finalResult = result.replace(/\\(.)/g,'$1')   //replacing escaped character here

console.log(finalResult);

答案 2 :(得分:0)

使用以下正则表达式可以有一种更简单的方法来完成相同的任务:

\\.|\*((\\.|[^*])+)\*

这个想法是匹配一个所需的字符串,该字符串应在所有转义字符都消耗完之后出现。我们尝试使用交替的第一面来匹配所有转义的字符,然后在第二次尝试中我们想要匹配所需的模式(如果存在)。

JS代码:

var str = `some text *some number \\* other number* more text`

console.log(str.replace(/\\.|\*((\\.|[^*])+)\*/g, function(match, $1) {
	return $1 ? '<strong>' + $1 + '</strong>' : match;
}));

故障:

  • \\.匹配转义字符
  • |
  • \*匹配文字*
  • (第一个捕获组的开始
    • (第二个捕获组的开始
      • \\.匹配转义字符
      • |
      • [^*]+匹配*以外的任何内容
    • )+第二个捕获组的结尾,重复一次或多次
    • )第一个捕获组的结尾
  • \*匹配文字*