Я ударяю головой о стену. Я хочу regex, который соответствует: пустая строка, A
, AB
, и ABC
, но нет AC
. У меня есть это, которое работает:
/^(A|AB|ABC)?$/
Но это - упрощение; в моем приложении A
, B
, и C
на самом деле длинные классы символов, таким образом, я не хочу повторять их много раз. Возможно, я просто не смотрю на него правильный путь. Я попробовал это:
/^((AB?)C?)?$/
Но это все еще соответствует AC
.
Есть ли более простой способ сделать это, которое могло быть расширено, чтобы (сказать), ABCD
, ABCDE
, и т.д.?
Править: Расширяются на ABCDE
, Я подразумеваю, что это соответствовало бы: пустая строка, A
, AB
, ABC
, ABCD
, ABCDE
. В основном, "запускается с" regex.
Попробуйте это регулярное выражение:
^(A(B(C)?)?)?$
Я думаю, что вы можете увидеть паттерн и расширить его для ABCD
и ABCDE
like:
^(A(B(C(D)?)?)?)?$
^(A(B(C(D(E)?)?)?)?)?$
Теперь каждая часть зависит от предшествующих частей (B зависит от A, C зависит от B, и т.д. ).
/^A(?:B(?:C)?)?$/
должно сделать это.
Это использование конструкции группы не захвата (?: xxx )
, чтобы не испортить любой захват совпадений, который вы, возможно, делаете.
Это кажется немного экстравагантным, но он работает на классах характера, а также персонажей.
(Вы всегда будете использовать indexOf, если он может быть выражен как строка.)
Вы имели возможность редактировать Regexp, но теперь вам нужен новый с любым изменением.
RegExp.prototype.extend= function(c){
var s= '', rx= this.toString();
rx= rx.replace(/(\W+)$/, c+'$1').replace(/^\/|\/$/g,'');
if(this.global) s+= 'g';
if(this.multiline) s+= 'm';
if(this.ignoreCase) s+= 'i';
return RegExp(rx, s);
}
String.prototype.longMatch= function(arr){
// if(this=='') return true;
var Rx= RegExp("^("+arr.shift()+")");
var i= 0, L= Math.min(s.length, arr.length),
M= this.match(Rx);
while(i< L){
if(!M) return false;
Rx= Rx.extend(arr[i++]);
M= this.match(Rx);
}
return M[0]==this;
}
var arr= ['A','B','C','D'];
var s= 'ABCD';// try various strings
alert(s.longMatch(arr));