Регулярное выражение для соответствия A, AB, ABC, но не AC. («начинается с»)

#java #regex

#javascript #регулярное выражение

Вопрос:

Я бьюсь головой о стену. Мне нужно регулярное выражение , которое соответствует: пустой строке, A , AB , и ABC , но не AC . У меня есть это, которое работает:

 /^(A|AB|ABC)?$/
 

Но это упрощение; в моем приложении A , B , и C на самом деле являются длинными символьными классами, поэтому я не хочу повторять их снова и снова. Может быть, я просто неправильно смотрю на это. Я попробовал это:

 /^((AB?)C?)?$/
 

Но это все равно совпадает AC .

Есть ли более простой способ сделать это, который можно было бы расширить (скажем), ABCD , ABCDE , и т.д.?

Редактировать: под расширением ABCDE я подразумеваю, что оно будет соответствовать: пустой строке, A , AB , ABC , ABCD , ABCDE . По сути, регулярное выражение «начинается с».

Комментарии:

1. Каким образом вы хотите его расширить?

2. C не может предшествовать an A или A за ним должен следовать a B ?

3. Итак, вы хотите разрешить ABCD , но не ACD и ABCDE но не ACDE ?

4. Извините, я уточнил, как я хотел, чтобы оно было расширено. Это своего рода регулярное выражение «начинается с», которое, я думаю, я действительно ищу.

Ответ №1:

Попробуйте это регулярное выражение:

 ^(A(B(C)?)?)?$
 

Я думаю, вы можете увидеть шаблон и расширить его для ABCD и ABCDE нравится:

 ^(A(B(C(D)?)?)?)?$
^(A(B(C(D(E)?)?)?)?)?$
 

Теперь каждая часть зависит от предшествующих частей (B зависит от A, C зависит от B и т. Д.).

Комментарии:

1. Спасибо. я не могу поверить, что я не подумал просто изменить группировку. и это легко расширить : ^(A(B(C(D(E)?)?)?)?)?$ . Этот сайт тоже очень быстрый, я пошел выпить кофе после публикации, и когда я вернулся, там уже было три правильных ответа

2. @CarlSmotricz на самом деле это работает безупречно, когда C не является ни одним символом.

Ответ №2:

 /^A(?:B(?:C)?)?$/
 

должно это сделать.

При этом используется конструкция группы без захвата (?: xxx ) , чтобы не испортить любой захват совпадений, который вы можете выполнять.

Комментарии:

1. Спасибо. чтобы сопоставить пустую строку, вам нужно будет сопоставить все это в другом (?: ... )?

2. @Jenni: да, это должен сделать другой уровень вложенности.

Ответ №3:

Это должно сделать это:

 /^A(BC?)?$/
 

Ответ №4:

Это кажется немного экстравагантным, но это работает как для классов персонажей, так и для персонажей.

(Вы всегда использовали бы indexOf, если бы он мог быть выражен в виде строки.)

Раньше вы могли редактировать регулярное выражение, но теперь вам нужно новое с любыми изменениями.

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