Какое регулярное выражение может соответствовать последовательности одного и того же символа? - PullRequest
39 голосов
/ 14 марта 2009

Мой друг спросил меня об этом, и я был озадачен: есть ли способ создать регулярное выражение, которое соответствует последовательности того же символа? Например, совпадать с «aaa», «bbb», но не с «abc»?

m|\w{2,3}| 

Не сработает, так как будет соответствовать 'abc'.

m|a{2,3}| 

Не сработает, так как не будет соответствовать 'bbb', 'ccc' и т. Д.

Ответы [ 7 ]

77 голосов
/ 14 марта 2009

Конечно! Группировка и ссылки ваших друзей:

(.)\1+

Будет соответствовать 2 или более вхождениям одного и того же персонажа. Только для символов, составляющих слово, используйте \w вместо ., то есть:

(\w)\1+
10 голосов
/ 14 марта 2009

Обратите внимание, что в Perl 5.10 у нас также есть альтернативные обозначения для обратных ссылок.

foreach (qw(aaa bbb abc)) {
  say;
  say ' original' if /(\w)\1+/;
  say ' new way'  if /(\w)\g{1}+/;
  say ' relative' if /(\w)\g{-1}+/;
  say ' named'    if /(?'char'\w)\g{char}+/;
  say ' named'    if /(?<char>\w)\k<char>+/;
}
4 голосов
/ 14 марта 2009

Это будет соответствовать более чем \ w , как @@@:

/(.)\1+/
1 голос
/ 20 марта 2009

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

(a* + b* + ... + z*)

Где a ... z - символы в конечном алфавите.

Так что регулярные выражения Perl, хотя и являются надмножеством чистых регулярных выражений, безусловно, имеют свои преимущества, даже если вы просто хотите использовать их для чистых регулярных выражений!

1 голос
/ 14 марта 2009

Для этого нужны обратные ссылки.

m/(\w)\1\1/

сделает свое дело.

0 голосов
/ 07 апреля 2018

Если вы используете Java и обнаруживаете повторяющиеся символы в данной строке, вот код,

public class Test {
public static void main(String args[]) {
    String s = "abbc";
    if (s.matches(".*([a-zA-Z])\\1+.*")) {
        System.out.println("Duplicate found!");
    } else {
        System.out.println("Duplicate not found!");
    }
}

}

0 голосов
/ 14 марта 2009

Отвечая на мой вопрос, но получил:

m|(\w)\1+|
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...