Я разделил свой ответ на четыре части.
Первый раздел содержит мое решение проблемы. Читатели, которых больше ничего не интересует, могут пропустить другие разделы.
Остальные три раздела связаны с идентификацией пар одинаковых цифр, которым предшествует другой di git и за которым следует другой di git . Им соответствует первый из трех разделов; другие два захватывают их в группу.
Я включил последний раздел, потому что хотел поделиться величайшим трюком с регулярным выражением с теми, кто с ним не знаком, потому что я нахожу его очень интересным. круто и умно, но все же просто. Это задокументировано здесь . Предупреждаем, что для создания интриги автор по этой ссылке включил длинную преамбулу перед барабанной дробью.
Определите, содержит ли строка две последовательные одинаковые цифры, которым предшествует другой di git, за которым следует другой di git
Вы можете проверить строку следующим образом:
import re
r = r'(\d)(?!\1)(\d)\2(?!\2)\d'
arr = ["123456678", "1123455a666788"]
for s in arr:
print(s, bool(re.search(r, s)) )
отображает
123456678 True
1123455a666788 False
Выполнить Python код | Запустите двигатель! 1
Механизм регулярных выражений выполняет следующие операции.
(\d) : match a digit and save to capture group 1 (preceding digit)
(?!\1) : next character cannot equal content of capture group 1
(\d) : match a digit in capture group 2 (first digit of pair)
\2 : match content of capture group 2 (second digit of pair)
(?!\2) : next character cannot equal content of capture group 2
\d : match a digit
(?!\1)
и (?!\2)
равны отрицательный просмотр вперед .
Используйте модуль Python s regex для сопоставления пар последовательных цифр, которые имеют желаемое свойство
Вы можете использовать следующее регулярное выражение с модулем Python regex
для получения совпадающих пар цифр.
r'(\d)(?!\1)\K(\d)\2(?=\d)(?!\2)'
Regex Engine
Механизм регулярных выражений выполняет следующие операций.
(\d) : match a digit and save to capture group 1 (preceding digit)
(?!\1) : next character cannot equal content of capture group 1
\K : forget everything matched so far and reset start of match
(\d) : match a digit in capture group 2 (first digit of pair)
\2 : match content of capture group 2 (second digit of pair)
(?=\d) : next character must be a digit
(?!\2) : next character cannot equal content of capture group 2
(?=\d)
- это положительный просмотр вперед . (?=\d)(?!\2)
можно заменить на (?!\2|$|\D)
.
Сохранить пары последовательных цифр, которые имеют желаемое свойство, в группу захвата
Другой способ получить совпадающие пары цифр, для которого не требуется модуль регулярных выражений, заключается в извлечении содержимого группы захвата 2 из совпадений следующего регулярного выражения.
r'(\d)(?!\1)((\d)\3)(?!\3)(?=\d)'
Re engine
Выполняются следующие операции.
(\d) : match a digit in capture group 1
(?!\1) : next character does not equal last character
( : begin capture group 2
(\d) : match a digit in capture group 3
\3 : match the content of capture group 3
) : end capture group 2
(?!\3) : next character does not equal last character
(?=\d) : next character is a digit
Используйте Величайший трюк с регулярным выражением , чтобы идентифицировать пары последовательных цифр, которые имеют желаемое свойство
Мы используем следующее регулярное выражение для сопоставления строки.
r'(\d)(?=\1)|\d(?=(\d)(?!\2))|\d(?=\d(\d)\3)|\d(?=(\d{2})\d)'
Когда есть совпадение, мы не обращаем внимания на то, какой символ был сопоставлен, а проверяем содержимое группы захвата 4 ((\d{2})
) , как я объясню ниже.
Уловка в действии
Первые три компонента чередования соответствуют способам, которым строка из четырех цифр может не иметь Имейте в виду, что вторая и третья цифры равны, первая и вторая не равны, а третья и четвертая равны. Это:
(\d)(?=\1) : assert first and second digits are equal
\d(?=(\d)(?!\2)) : assert second and third digits are not equal
\d(?=\d(\d)\3) : assert third and fourth digits are equal
Отсюда следует, что если есть совпадение di git и первые три части чередования терпят неудачу, последняя часть (\d(?=(\d{2})\d)
) должна быть успешной, и группа захвата он содержит (# 4) должен содержать две одинаковые цифры, которые имеют требуемые свойства. (Последний \d
необходим, чтобы утверждать, что за парой интересующих цифр следует di git.)
Если есть совпадение, как мы определяем, является ли последняя часть чередования тот, который соответствует?
Когда это регулярное выражение соответствует di git, нас не интересует, что это было за di git. Вместо этого мы ищем группу 4 ((\d{2})
). Если эта группа пуста, мы заключаем, что один из первых трех компонентов чередования соответствует di git, что означает, что две цифры, следующие за сопоставленным di git, не обладают свойствами, равными и не равными цифры, предшествующие и следующие за ними.
Если, однако, группа захвата 4 не пуста, это означает, что ни одна из первых трех частей чередования не соответствовала di git, поэтому последняя часть чередования должна совпадать, а две цифры, следующие за совпадающими di git, которые содержатся в группе захвата 4, имеют требуемые свойства.
1. Переместите курсор для получения подробных объяснений.