Javascript 查找字符串中的字符,但更喜欢具有NFA且不带原子分组的连续字符
我正在尝试创建一个正则表达式,它可以在字符串中的任何位置找到字符。我更希望他们能先找到连续的角色 让我举一个例子,假设Javascript 查找字符串中的字符,但更喜欢具有NFA且不带原子分组的连续字符,javascript,regex,Javascript,Regex,我正在尝试创建一个正则表达式,它可以在字符串中的任何位置找到字符。我更希望他们能先找到连续的角色 让我举一个例子,假设s='这是一个测试字符串',我正在搜索tst,我想这样找到它: // Correct // v vv s = 'this is a test test string' 而不是: // Incorrect // v v v s = 'this is a test test string' 如果s='这是一个测试tst字符串' //
s='这是一个测试字符串'
,我正在搜索tst
,我想这样找到它:
// Correct
// v vv
s = 'this is a test test string'
而不是:
// Incorrect
// v v v
s = 'this is a test test string'
如果
s='这是一个测试tst字符串'
// Correct
// vvv
s = 'this is a test test tst string'
有几件事需要注意:
- 搜索字符由用户提供(
在本例中)tst
- 我使用的是javascript,所以我不能支持atomi分组,我想这会让这更容易
var find = 'tst';
var rStarts = [];
var rEnds = [];
for (var i = 0; i < find.length - 1; i++) {
rStarts.push(= '(' + find[i] + find[i + 1] )
rEnds.push( find[i] + '[^]*?' + find[i + 1] + ')' );
}
var find='tst';
var rStarts=[];
var rEnds=[];
for(var i=0;i
但中途我意识到我不知道我要带着它去哪里。
有什么办法吗?好吧,我还是不确定你到底在找什么,但也许第一次尝试就可以了:
.*?(t)(s)(t)|.*?(t)(s).*?(t)|.*?(t).*?(s)(t)|(t).*?(s).*?(t)
我在这里捕捉每个字母,但如果你不介意将它们分组
.*?(tst)|.*?(ts).*?(t)|.*?(t).*?(st)|(t).*?(s).*?(t)
这将与您在问题中提到的部分相匹配。好吧,我仍然不确定您到底在寻找什么,但也许第一次尝试就可以了:
.*?(t)(s)(t)|.*?(t)(s).*?(t)|.*?(t).*?(s)(t)|(t).*?(s).*?(t)
我在这里捕捉每个字母,但如果你不介意将它们分组
.*?(tst)|.*?(ts).*?(t)|.*?(t).*?(st)|(t).*?(s).*?(t)
这将与您在问题中提到的部分相匹配。您可以这样做:
var find = 'tst';
var rStarts = [];
var rEnds = [];
for (var i = 0; i < find.length - 1; i++) {
rStarts.push(= '(' + find[i] + find[i + 1] )
rEnds.push( find[i] + '[^]*?' + find[i + 1] + ')' );
}
按照您喜欢的顺序计算针的所有子字符串组合的正则表达式,并按顺序匹配它们。因此,对于您的测试,您可以进行以下匹配:
/(tst)/
/(ts).*(t)/
/(t).*(st)/ // <- this one matches
/(t).*(s).*(t)/
/(tst)/
/(ts)。*(t)/
/(t) .*(st)//您可以执行以下操作:
var find = 'tst';
var rStarts = [];
var rEnds = [];
for (var i = 0; i < find.length - 1; i++) {
rStarts.push(= '(' + find[i] + find[i + 1] )
rEnds.push( find[i] + '[^]*?' + find[i + 1] + ')' );
}
按照您喜欢的顺序计算针的所有子字符串组合的正则表达式,并按顺序匹配它们。因此,对于您的测试,您可以进行以下匹配:
/(tst)/
/(ts).*(t)/
/(t).*(st)/ // <- this one matches
/(t).*(s).*(t)/
/(tst)/
/(ts)。*(t)/
/(t) .*(st)//这将查找所提供的一组字母的最短集合:
function findChars(chars,string)
{
var rx = new RegExp(chars.split("").join(".*?"),"g");
var finds = [];
while(res = rx.exec(string))
{
finds.push(res[0]);
rx.lastIndex -= res[0].length-1;
}
finds.sort(function(a,b) { return a.length-b.length; })
return finds[0];
}
var s2 = 'this is a test test tst string';
console.log(findChars('tst',s2));//"tst"
console.log(findChars('ess',s2));//"est ts"
这将查找所提供字母组的最短集合:
function findChars(chars,string)
{
var rx = new RegExp(chars.split("").join(".*?"),"g");
var finds = [];
while(res = rx.exec(string))
{
finds.push(res[0]);
rx.lastIndex -= res[0].length-1;
}
finds.sort(function(a,b) { return a.length-b.length; })
return finds[0];
}
var s2 = 'this is a test test tst string';
console.log(findChars('tst',s2));//"tst"
console.log(findChars('ess',s2));//"est ts"
可以使用lookaheads来模拟原子组,如中所述。这个正则表达式似乎做了我们想要做的事情:
/^(?:(?=(.*?tst))\1|(?=(.*?ts.+?t))\2|(?=(.*?t.+?st))\3|(?=(.*?t.+?s.+?t))\4)/
…或以人类可读的形式:
^
(?:
(?=(.*?tst))\1
|
(?=(.*?ts.+?t))\2
|
(?=(.*?t.+?st))\3
|
(?=(.*?t.+?s.+?t))\4
)
您可以使用lookaheads来模拟原子群,如中所述。这个正则表达式似乎做了我们想要做的事情:
/^(?:(?=(.*?tst))\1|(?=(.*?ts.+?t))\2|(?=(.*?t.+?st))\3|(?=(.*?t.+?s.+?t))\4)/
…或以人类可读的形式:
^
(?:
(?=(.*?tst))\1
|
(?=(.*?ts.+?t))\2
|
(?=(.*?t.+?st))\3
|
(?=(.*?t.+?s.+?t))\4
)
为什么第一个不是“这是一个测试字符串”?(添加空格是因为网站会吃掉星号)因为我希望正则表达式更喜欢彼此相邻的字符,然后在开始时更喜欢匹配。好吧,那么为什么不“这是一个测试字符串”或“这是一个测试字符串”?@Jerry我认为不可能创建一个可以做到这一点的正则表达式(你的第一个示例),不想要第二个,因为它在字符串中较晚。但我会选择任何一种情况,为什么第一个不是“这是一个测试字符串”?(添加空格是因为网站会吃掉星号)因为我希望正则表达式更喜欢彼此相邻的字符,然后在开始时更喜欢匹配。好吧,那么为什么不“这是一个测试字符串”或“这是一个测试字符串”?@Jerry我认为不可能创建一个可以做到这一点的正则表达式(你的第一个示例),不想要第二个,因为它在字符串中较晚。但我认为这两种情况都不匹配:这是一个测试tststring@MosheK固定的。我之前遗漏了一些内容。这不匹配:这是一个测试tststring@MosheK固定的。我之前省略了一些内容。当输入字符串超过5个字符时,这不是会变得非常昂贵吗?虽然要匹配的regexp的数量确实会随着指针中的字母数量快速增长,但我认为您不会遇到少量字母的问题。记住,你一次只需要匹配一个,你找到的第一个匹配也应该是最好的,你正在寻找的那个。。。。我还考虑了一种只使用indexOf的不同算法,这确实是我的第一次尝试,但它的递归性质让我感到困扰。我甚至不确定它是否会更快。当输入字符串超过5个字符时,这不是会变得非常昂贵吗?虽然要匹配的regexp的数量确实会随着指针中的字母数量快速增长,但我不认为您会遇到少量字母的问题。记住,你一次只需要匹配一个,你找到的第一个匹配也应该是最好的,你正在寻找的那个。。。。我还考虑了一种只使用indexOf的不同算法,这确实是我的第一次尝试,但它的递归性质让我感到困扰。我甚至不确定它是否会更快。