Регулярное выражение для обнаружения повторения в строке - PullRequest
8 голосов
/ 03 июня 2009

Можно ли обнаружить повторяющиеся числовые шаблоны с помощью регулярного выражения?

Так, например, если бы у меня была следующая строка "034503450345", можно ли было бы соответствовать повторяющейся последовательности 0345? У меня такое чувство, что это выходит за рамки регулярных выражений, но я решил спросить здесь, чтобы узнать, пропустил ли я что-то.

Ответы [ 5 ]

19 голосов
/ 03 июня 2009

Это выражение будет соответствовать одной или нескольким повторяющимся группам:

(.+)(?=\1+)


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

(?x)  # enable regex comment mode
(     # start capturing group
.+    # one or more of any character (excludes newlines by default)
)     # end capturing group
(?=   # begin lookahead
\1+   # match one or more of the first capturing group
)     # end lookahead


Чтобы соответствовать определенному шаблону, измените .+ на этот шаблон, например, \d+ для одного или нескольких чисел или \d{4,} для совпадения с 4 или более числами.

Чтобы соответствовать определенному номеру шаблона, измените \1+, например, на \1{4} для четырех повторений.

Чтобы повторение не было рядом друг с другом, вы можете добавить .*? в поле зрения.

9 голосов
/ 03 июня 2009

Да, вы можете - вот тестовый пример Python

import re
print re.search(r"(\d+).*\1", "8034503450345").group(1)
# Prints 0345

Регулярное выражение гласит: «найдите некоторую последовательность цифр, затем любое количество других вещей, затем ту же самую последовательность снова».

На едва заметной ноте вот одно из моих любимых регулярных выражений - детектор простых чисел:

import re
for i in range(2, 100):
    if not re.search(r"^(xx+)\1+$", "x"*i):
        print i
8 голосов
/ 03 июня 2009

Просто чтобы добавить примечание к (правильному) ответу от RichieHindle:

Обратите внимание, что хотя реализация Python для регулярных выражений (и многие другие, например, Perl) могут это делать, это больше не является регулярным выражением в узком смысле слова.

Ваш пример не является регулярным языком, поэтому не может быть обработан чисто регулярным выражением. Смотрите, например Отличная статья в Википедии для подробностей.

Хотя это в основном только академический интерес, существуют некоторые практические последствия. Реальные регулярные выражения могут дать гораздо лучшие гарантии для максимального времени выполнения, чем в этом случае. Так что в какой-то момент у вас могут возникнуть проблемы с производительностью.

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

2 голосов
/ 03 июня 2009

Это код C #, который использует конструкцию обратной ссылки для поиска повторяющихся цифр. Он будет работать с 034503450345, 123034503450345, 034503450345345, 232034503450345423. Регулярное выражение намного проще и понятнее.

/// <summary>
/// Assigns repeated digits to repeatedDigits, if the digitSequence matches the pattern
/// </summary>
/// <returns>true if success, false otherwise</returns>
public static bool TryGetRepeatedDigits(string digitSequence, out string repeatedDigits)
{
    repeatedDigits = null;

    string pattern = @"^\d*(?<repeat>\d+)\k<repeat>+\d*$";

    if (Regex.IsMatch(digitSequence, pattern))
    {
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
        repeatedDigits = r.Match(digitSequence).Result("${repeat}");
        return true;
    }
    else
        return false;
}
0 голосов
/ 13 января 2013

Используйте регулярное выражение: бар {2} ищет текст с двумя или более полосами: Barbar barbarbar ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...