判断给定更多输入时,值是否可能匹配一个正则表达式

4

我目前正在使用JavaScript编写一个应用程序,其中我正在将输入与正则表达式进行匹配,但我还需要找到一种方法,如何将字符串与正则表达式的部分进行匹配。

例如:

var invalid = "x",
    potentially = "g",
    valid = "ggg", 
    gReg = /^ggg$/;

gReg.test(invalid); //returns false (correct)
gReg.test(valid);   //returns true (correct)

现在我需要找到一种方法来确定变量 "potentially" 的值是否与正则表达式“/^ggg$/”不完全匹配,但是随着更多输入,它有可能匹配!例如,在这种情况下,“potentially”变量是“g”,但如果再添加两个“g”字母,则将匹配正则表达式“/^ggg$/”。不过,在“invalid”的情况下,无论你添加多少字符,它都无法匹配正则表达式“/^ggg$/”。那么,我该如何确定一个字符串是否具有或具备潜力匹配特定的正则表达式呢?

"invalid"和"potentially"长度相同,但前者永远无法匹配表达式,而后者可以...只要提供更多的输入。 - Andreas Grech
1
/^abc$/的情况下,可能的匹配是什么?它只包括aab吗?还是包括bcbc甚至ac?如果只有aab,我们可以使用/^a(bc?)?$/ - Amarghosh
你能不能只是创建一个可能不那么严格的表达式/^g{1,3}$/并测试一下呢? - Alex K.
2
你可以使用 a(bc?)? 来计算长度为三的字符串。随着字符串长度的增加,正则表达式也会变得更长:/^a(b(cd?)?)?$/。尝试编写一个正则表达式生成器 - 这并不难。 - Amarghosh
1
有关近似重复问题的详细讨论,请参阅https://dev59.com/e3E95IYBdhLWcg3wEpzo。 - Tim Pietzcker
显示剩余2条评论
5个回答

1

试试这个:

var str = "abcdefgh";
var len = str.length;
var reg = "";
for(var i = str.length - 1; i > 0; i--)
{
  //replace '(' with '(?:' to make it non capturing.
  reg = '(' + str[i] + reg + ')?'; 
}
reg = "^" + str[0] + reg + "$";

var regex = new RegExp(reg);

只有当你的正则表达式是一个平面字符串时,这才有效。如果你的正则表达式是像 aaa|bbb 这样的东西,结果就不是你想要的了。 - ealdent

1
你可以试着“反向”思考一下,将这个“潜在的可能性”转化为一个正则表达式,并在另一个方向上进行测试。例如:
var invalid = "x",
    potentially = "g",
    valid = "ggg", 
    validReg = new RegExp("^"+valid+"$"),
    invalidReg = new RegExp(invalid),
    potentialReg = new RegExp(potentially);

//test actual matches
validReg.test(invalid); //returns false (correct)
validReg.test(valid);   //returns true (correct)

//test potential matches
potentialReg.test(valid); //returns true
invalidReg.test(valid);   //returns false

0

显然下面的测试函数不会完全符合你的要求...但希望它能给你解决问题的思路。

function test(reg,string){
   var r = reg.exec(string);
     if(r){
         if(r.pop()){
             return true;
         }
         return "potentially";
     }
     return false;
}

var invalid = "x",
    potentially = "a",
    potentially2 = "ab",
    valid = "abc", 
    gReg = /^a(b(c)?)?$/;

alert(test(gReg,invalid)); //returns false (correct)
alert(test(gReg,potentially));   //returns "potentially" (correct)
alert(test(gReg,potentially2));   //returns "potentially" (correct)
alert(test(gReg,valid));   //returns true (correct)

0
function have_potential(input, valid) {
    if ( (new RegExp('^' + valid + '$')).test(input) ) return false;
    if ( (new RegExp(input)).test( valid ) ) return true;
    return false;
}

var valid = 'aaa|bbb';

console.log( have_potential('a',valid) )
// true
console.log( have_potential('c',valid) )
// false
console.log( have_potential('aaa',valid) )
// false

编辑:

简化版本
function have_potential(input, valid) {
    return ( (new RegExp(input)).test( valid ) && !(new RegExp('^' + valid + '$')).test(input) );
}

编辑2: 在第一位使用indexOf会更好。该函数需要扁平字符串输入,而“valid”可能包含由“|”分隔的列表。

function have_potential(input, valid) {
    return ( valid.indexOf(input) !== -1 && !(new RegExp('^' + valid + '$')).test(input) );
}

不幸的是,我认为这只是偶然发生的。 console.log(have_potential('a|b', valid) // => true - ealdent
如果您可以确保您的正则表达式仅检查平面字符串(虽然这放弃了使用正则表达式的所有优势),那么这个解决方案非常好。 - ealdent

0

没有通用的解决方案。如果正则表达式是一个简单的字符串,就像示例中的那个(在这种情况下根本没有使用正则表达式的意义),您可以使用简单的字符串比较:

var invalid = "x",
potentially = "g",
valid = "ggg";
var gReg = "ggg";

function test(t, s) {
  if (t === s) return true;
  if (t.indexOf(s) === 0) return "potentially";
  return false;
}

test(gReg, invalid);     // false
test(gReg, potentially); // "potentially"
test(gReg, valid);       // true

否则,您可以手动构建另一个正则表达式,该表达式接受gReg接受的每个字符串前缀。您将不得不大量使用()?。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接