正则表达式如何匹配除单词以外的所有符号?
需要找到除单词以外的所有符号。
(.*)
-查找所有符号。
[^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>
答案 0 :(得分:4)
这项技术的一个关键(我将多次返回该关键)是我们完全忽略了正则表达式引擎返回的总体匹配:那就是垃圾箱。相反,我们检查第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;
})
)
使用
.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+"]";
}
并解释了错误所在-您将否定的前瞻符号放在了|
字符后 之后。这意味着匹配引擎将执行以下操作:
|video|
,因为该模式可以使用|
end
,它位于否定的前瞻中。|
end
|
字符,因为这可以通过负向查找,并且也可以与.*?
一起使用| |
序列,因为单词的开头中的|
被先前的匹配所消耗。所以您最终匹配了以下内容
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
是-空白(显示效果不是很好,但是),找到的偏移量为
12
,20
,26
|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 + "]"
}
}