Определение, могут ли значения потенциально соответствовать регулярному выражению, учитывая больше ввода - PullRequest
4 голосов
/ 23 апреля 2010

В настоящее время я пишу приложение на 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$/, независимо от того, сколько символов вы добавите к нему.


Итак, как я могу определить, имеет ли строка совпадение с определенным регулярным выражением или нет?

Ответы [ 5 ]

1 голос
/ 23 апреля 2010

Как насчет того, чтобы просто «обратить» свое мышление на это и превратить «потенциал» в регулярное выражение, проверяя в другом направлении, например,

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
1 голос
/ 23 апреля 2010

Попробуйте это:

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);
0 голосов
/ 23 апреля 2010

Нет общего решения. Если регулярное выражение является простой строкой, как в примере (в этом случае вообще нет смысла использовать регулярное выражение), вы можете использовать простое сравнение строк:

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. Вам придется использовать ()? много.

0 голосов
/ 23 апреля 2010
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

Edit: укороченная версия

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

Edit2: indexOf будет лучше на первом месте. функция требует ввода плоской строки, и «valid» может содержать список, разделенный «|»

function have_potential(input, valid) {
    return ( valid.indexOf(input) !== -1 && !(new RegExp('^' + valid + '$')).test(input) );
}
0 голосов
/ 23 апреля 2010

Очевидно, что тестовая функция, представленная ниже, не будет именно тем, что вам нужно ... надеюсь, она даст вам представление о том, как решить проблему.

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)
...