0

我正在尝试创建一个正则表达式,它将在字符串中的任何位置找到字符。不过,我希望他们首先找到连续的字符。

让我举个例子,假设s = 'this is a test test string'我正在寻找tst我想像这样找到它:

// Correct
//   v           vv
s = 'this is a test test string'

并不是:

// Incorrect
//   v  v         v
s = 'this is a test test string'

还有如果s = 'this is a test test tst string'

// 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] + ')' );
}

但是在进行到一半时,我意识到我不知道我要去哪里。任何想法如何做到这一点?

4

4 回答 4

1

找到一组提供的字母的最短集合:

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"
于 2013-09-16T15:45:17.643 回答
1

好吧,我仍然不确定你在寻找什么,但也许第一次尝试就可以了:

.*?(t)(s)(t)|.*?(t)(s).*?(t)|.*?(t).*?(s)(t)|(t).*?(s).*?(t)

正则表达式101演示

我在这里捕获了每个字母,但是如果您不介意将它们分组...

.*?(tst)|.*?(ts).*?(t)|.*?(t).*?(st)|(t).*?(s).*?(t)

这将与您在问题中提到的部分相匹配。

于 2013-09-16T15:02:09.330 回答
1

你可以这样做:

按照您喜欢的顺序计算针的所有子串组合的正则表达式,并按顺序匹配它们。因此,对于您的测试,您可以进行以下匹配:

/(tst)/
/(ts).*(t)/
/(t).*(st)/  // <- this one matches
/(t).*(s).*(t)/

计算正则表达式很棘手,并且使它们以正确的顺序排列取决于您是否更喜欢 4-1-1 拆分而不是 2-2-2 拆分。

于 2013-09-16T15:12:27.013 回答
0

您可以使用前瞻来模拟原子组,如本文所述。这个正则表达式似乎做想做的事:

/^(?:(?=(.*?tst))\1|(?=(.*?ts.+?t))\2|(?=(.*?t.+?st))\3|(?=(.*?t.+?s.+?t))\4)/

...或以人类可读的形式:

^
(?:
   (?=(.*?tst))\1
   |
   (?=(.*?ts.+?t))\2
   |
   (?=(.*?t.+?st))\3
   |
   (?=(.*?t.+?s.+?t))\4
)

参考

于 2013-09-16T17:22:12.327 回答