Javascript:负的lookback等价物?
有没有一种方法可以在javascript正则表达式中实现a的等价物?我需要匹配一个不以特定字符集开头的字符串 如果在字符串的开头找到匹配的部分,我似乎无法找到一个不失败的正则表达式。负面外观落后似乎是唯一的答案,但javascript没有 编辑: 这是我想使用的正则表达式,但它不:Javascript:负的lookback等价物?,javascript,regex,negative-lookbehind,Javascript,Regex,Negative Lookbehind,有没有一种方法可以在javascript正则表达式中实现a的等价物?我需要匹配一个不以特定字符集开头的字符串 如果在字符串的开头找到匹配的部分,我似乎无法找到一个不失败的正则表达式。负面外观落后似乎是唯一的答案,但javascript没有 编辑: 这是我想使用的正则表达式,但它不: ( 因此,它将匹配“jim”或“m”中的“m”,而不是“jam”使用 newString = string.replace(/([abcdefg])?m/, function($0,$1){ return $1?$0
(
因此,它将匹配“jim”或“m”中的“m”,而不是“jam”使用
newString = string.replace(/([abcdefg])?m/, function($0,$1){ return $1?$0:'m';});
Mijoja的策略适用于您的具体案例,但不适用于一般情况:
js>newString = "Fall ball bill balll llama".replace(/(ba)?ll/g,
function($0,$1){ return $1?$0:"[match]";});
Fa[match] ball bi[match] balll [match]ama
这里有一个例子,目标是匹配双l,但如果前面有“ba”,则不匹配。请注意“balll”一词--true Lookback本应抑制前两个l,但与第二对匹配。但通过匹配前两个l,然后将该匹配视为假阳性而忽略,则regexp引擎将从该匹配结束时开始,并忽略假阳性中的任何字符。自2018年以来,都是错误的一部分
//正向查找
(?
回答2018年前的问题
由于Javascript支持,一种方法是:
反转输入字符串
与反向正则表达式匹配
反转并重新格式化匹配项
示例1:
以下是@andrew ensley的问题:
test(['jim', 'm', 'jam'], /m(?!([abcdefg]))/)
(?<!([abcdefg]))m
产出:
jim true token: m
m true token: m
jam false token: Ø
max-height true token: height
line-height false token: Ø
示例2:
在@neaumusic注释之后(匹配max height
,但不匹配line height
,标记为height
):
产出:
jim true token: m
m true token: m
jam false token: Ø
max-height true token: height
line-height false token: Ø
可以通过对角色集求反来定义非捕获组:
(?:[^a-g])m
…将匹配每一个m
而不是前面有这些字母的任何一个。/(?![abcdefg])[^abcdefg]m/gi
是的,这是一个技巧。让我们假设您要查找所有int
前面没有无符号的:
支持负面回顾:
(?<!unsigned )int
((?!unsigned ).{9}|^.{0,8})int
基本上,这个想法是获取n个前面的字符并排除带有负向前看的匹配,但也要匹配没有前面n个字符的情况(其中n是向后看的长度)
因此,所讨论的正则表达式:
test(['jim', 'm', 'jam'], /m(?!([abcdefg]))/)
(?<!([abcdefg]))m
您可能需要使用捕获组来找到您感兴趣的字符串的确切位置,或者您想用其他内容替换特定部分。遵循Mijoja的想法,并从JasonS暴露的问题中吸取教训,我有了这个想法;我检查了一点,但对自己没有把握,因此由比您更专业的人进行验证我在js正则表达式中会很棒:)
我的个人产出:
Fa[match] ball bi[match] bal[match] [match]ama
原则是在字符串中任意两个字符之间的每个点调用检查器
,只要该位置是以下内容的起点:
---不需要的大小的任何子字符串(此处为'ba'
,因此为。
)(如果已知该大小,否则可能更难实现)
------或小于字符串开头的值:^.?
然后呢,
---实际需要查找的内容(此处'll'
)
每次调用checker
,都会有一个测试来检查ll
之前的值是否不是我们不想要的(!==“ba”
);如果是这样,我们调用另一个函数,它必须是这个(doer
)这将对str进行更改,如果目的是此更改,或者更一般地说,将输入必要的数据以手动处理str
的扫描结果
在这里,我们更改字符串,因此需要保留长度差异的跟踪,以抵消replace
给出的位置,所有这些位置都是在str
上计算的,而str本身从未更改
由于原语字符串是不可变的,我们本可以使用变量str
来存储整个操作的结果,但我认为这个例子已经被替换复杂了,使用另一个变量(stru done
)会更清楚
我想,就性能而言,它一定是相当苛刻的:所有这些毫无意义的“替换”为“”,这个str.length-1
倍,再加上doer的手动替换,这意味着大量的切片。。。
可能在上面这个特定的情况下,可以通过将字符串仅切割一次来分组,在需要插入[match]
和.join()
的地方插入[match]
本身
另一件事是,我不知道它将如何处理更复杂的情况,也就是说,假查找的复杂值……长度可能是最有问题的数据
而且,在checker
中,如果$behind有多个非想要的值,我们必须使用另一个正则表达式(最好在checker
外部缓存(创建),以避免每次调用checker
时创建相同的正则表达式对象)知道这是否是我们想要避免的
希望我已经说清楚了;如果没有,不要犹豫,我会努力做得更好。这有效地做到了
"jim".match(/[^a-g]m/)
> ["im"]
"jam".match(/[^a-g]m/)
> null
搜索和替换示例
"jim jam".replace(/([^a-g])m/g, "$1M")
> "jiM jam"
请注意,负查找字符串必须为1个字符长,才能工作。使用您的大小写,如果要将m
替换为某个内容,例如,将其转换为大写的m
,则可以在捕获组中对集合进行求反
匹配([^a-g])m
,替换为$1M
"jim jam".replace(/([^a-g])m/g, "$1M")
\\jiM jam
([^a-g])
将匹配a-g
范围内任何非(^
)字符,并将其存储在第一个捕获组中,因此您可以使用$1
访问它
因此,我们在jim
中找到im
,并将其替换为im
,这导致jim
在2018年进入了市场
正向查找用法:
<代码
str.split('').reverse().join('').split(/@(?!$)/).map(s => s.split('').reverse().join('')).reverse()
function TestSORegEx() {
var s = "Donald Trump doesn't like jam, but Homer Simpson does.";
var reg = /(?![abcdefg])(.{1})(m)/gm;
var out = "Matches and groups of the regex " +
"/(?![abcdefg])(.{1})(m)/gm in \ns = \"" + s + "\"";
var match = reg.exec(s);
while(match) {
var start = match.index + match[1].length;
out += "\nWhole match: " + match[0] + ", starts at: " + match.index
+ ". Desired match: " + match[2] + ", starts at: " + start + ".";
match = reg.exec(s);
}
out += "\nResulting string after statement s.replace(reg, \"$1*$2*\")\n"
+ s.replace(reg, "$1*$2*");
alert(out);
}