正则表达式匹配所有符号,但单词除外

时间:2019-04-05 13:20:07

标签: javascript regex

正则表达式如何匹配除单词以外的所有符号?

需要找到除单词以外的所有符号。

(.*)-查找所有符号。

[^v]-查找除字母v之外的所有符号

但是如何找到除单词以外的所有符号

解决方案(写在下面):

((?:(?!here any word for block)[\s\S])*?)

((?:(?!here any word for block).)*?)

((?:(?!video)[\s\S])*?)


我想查找|end|以外的所有内容,并替换`| end |以外的所有内容。

我尝试:

|end|之外的所有其他

var str = '|video| |end| |water| |sun| |cloud|';
// May be:
//var str = '|end| |video| |water| |sun| |cloud|';
//var str = '|cloud| |video| |water| |sun| |end|';

str.replace(/\|((?!end|end$).*?)\|/gm, test_fun2);

function test_fun2(match, p1, offset, str_full) {
  console.log("--------------");
  p1 = "["+p1+"]";
  console.log(p1);
  console.log("--------------");
  return p1;
}

输出控制台日志:

--------------
[video]
--------------
--------------

--------------
--------------

--------------
--------------

--------------

示例需要什么:

[video](以外的任何符号

输入-'[video](text-1 *******any symbols except: "[video](" ******* [video](text-2 any symbols) [video](text-3 any symbols) [video](text-4 any symbols) [video](text-5 any symbols)'

输出-<div>text-1 *******any symbols except: "[video](" *******</div> <div>text-2 any symbols</div><div>text-3 any symbols</div><div>text-4 any symbols</div><div>text-5 any symbols</div>

3 个答案:

答案 0 :(得分:4)

场景1

使用best trick ever

  

这项技术的一个关键(我将多次返回该关键)是我们完全忽略了正则表达式引擎返回的总体匹配:那就是垃圾箱。相反,我们检查第1组匹配项,该匹配项在设置后包含我们要查找的内容。

解决方案:

s = s.replace(/\|end\||\|([^|]*)\|/g, function ($0, $1) { 
    return $1 ? "[" + $1 + "]" : $0; 
});

详细信息

  • \|end\|-|end|已匹配
  • |-或
  • \|([^|]*)\|-|被匹配,除|以外的任何0+个字符被捕获到组1中,然后|被匹配。

如果第1组匹配($1 ?),则替换发生,否则,整个匹配项$0返回结果。

JS测试:

console.log(
   "|video| |end| |water| |sun| |cloud|".replace(/\|end\||\|([^|]*)\|/g, function ($0, $1) { 
        return $1 ? "[" + $1 + "]" : $0; 
    })
)

场景2

使用

.replace(/\[(?!end])[^\]]*]\(((?:(?!\[video]\()[\s\S])*?)\)/g, '<div>$1</div>')

请参见regex demo

详细信息

  • \[-一个[字符
  • (?!end])-当前位置之后不允许end]
  • [^\]]*-除][以外的0多个字符
  • ]-一个]字符
  • \(-一个(字符
  • ((?:(?!\[video])[\s\S])*?)-第1组,捕获了0个或多个出现的任何字符([\s\S]),但不启动*?的字符却尽可能少([video]()字符序列
  • \)-一个)字符。

答案 1 :(得分:2)

这样的事情最好分多个步骤完成。另外,如果您要匹配内容,则应使用match

var str = '|video| |end| |water| |sun| |cloud|';
var matches = str.match(/\|.*?\|/g);

// strip pipe characters...
matches = matches.map(m=>m.slice(1,-1));

// filter out unwanted words
matches = matches.filter(m=>!['end'].includes(m));
           // this allows you to add more filter words easily
           // if you'll only ever need "end", just do (m=>m!='end')

console.log(matches); // ["video","water","sun","cloud"]

请注意,这更容易理解正在发生的事情,并且在将来需要时更易于维护和更改。

答案 2 :(得分:2)

您处在正确的轨道上。这是您需要使用正则表达式的地方:

var str = '|video| |end| |water| |sun| |cloud|';

console.log(str.replace(/(?!\|end\|)\|(\S*?)\|/gm, test_fun2));

function test_fun2(match, p1, offset, str_full) {
  return "["+p1+"]";
}

并解释了错误所在-您将否定的前瞻符号放在了|字符后 之后。这意味着匹配引擎将执行以下操作:

  1. 匹配|video|,因为该模式可以使用
  2. 抓住下一个|
  3. 发现下一个文本为end,它位于否定的前瞻中。
  4. 紧紧抓住| end
  5. 抓住空格和下一个|字符,因为这可以通过负向查找,并且也可以与.*?一起使用
  6. 继续捕获中间的| |序列,因为单词的开头中的|被先前的匹配所消耗。

所以您最终匹配了以下内容

var str = '|video| |end| |water| |sun| |cloud|';
           ^^^^^^^     ^^^     ^^^   ^^^
|video| ______|         |       |     |
| | ____________________|       |     |
| | ____________________________|     |
| | __________________________________|

全部是因为|end比赛被取消。

如果您打印出匹配项,就可以看到

var str = '|video| |end| |water| |sun| |cloud|';

str.replace(/\|((?!end|end$).*?)\|/gm, test_fun2);

function test_fun2(match, p1, offset, str_full) {
  console.log(match, p1, offset);
}

您将看到第二,第三和第四match| |,捕获的项目p1-空白(显示效果不是很好,但是),找到的偏移量为122026

|video| |end| |water| |sun| |cloud|
01234567890123456789012345678901234
            ^       ^     ^
12 _________|       |     |
20 _________________|     |
26 _______________________|

我所做的更改是,以负前瞻的方式显式地查找|end|模式,并且仅匹配非空格字符,因此您不必再抓住| |

还值得注意的是,您可以将过滤逻辑移至替换回调而不是正则表达式。这简化了正则表达式,但使替换更加复杂。尽管如此,这还是一个公平的权衡,因为如果您遇到更复杂的条件,代码通常更易于维护:

var str = '|video| |end| |water| |sun| |cloud|';

//capturing word characters - an alternative to "non-whitespace"
console.log(str.replace(/\|(\w*)\|/gm, test_fun2)); 

function test_fun2(match, p1, offset, str_full) {
  if (p1 === 'end') {
    return match;
  } else {
    return "[" + p1 + "]"
  }
}