Regex обратная ссылка, чтобы соответствовать противоположному случаю - PullRequest
0 голосов
/ 05 декабря 2018

Прежде чем я начну - возможно, стоит заявить, что: это технически не нужно решать с помощью регулярных выражений, просто я сразу подумал о регулярном выражении, когда начал решать эту проблему, иМне интересно узнать, возможно ли решить с помощью Regex.


Последние пару часов я пытался создать Regex, который выполняет следующие действия.

Регулярное выражение должно соответствовать строке длиной десять символов, если первые пять символов и последние пять символов идентичны, но каждый отдельный символ противоположен в случае.

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

Например,регулярное выражение должно соответствовать abCDeABcdE, так как первые пять символов и последние пять символов одинаковы, но каждый соответствующий символ противоположен в случае.Другими словами, flip_case("abCDe") == "ABcdE"

Вот еще несколько строк, которые должны соответствовать: abcdeABCDE, abcdEABCDe, zYxWvZyXwV.

И вотнесколько, которые не должны совпадать:

  • abcdeABCDZ, хотя дело обстоит иначе, сами строки не совпадают.
  • abcdeABCDe, очень близкое совпадение,но не должны совпадать, так как e не являются противоположными в случае.

Вот первое из приведенных мной регулярных выражений, которое, очевидно, неверно, поскольку не учитывает процесс смены регистра.

/([a-zA-Z]{5})\1/g

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

/([A-Z])[\1+32]/g

Этот новый regex (который, очевидно, не работает) должен соответствовать одной заглавной букве, сразусопровождаемый собой-плюс-32-ascii, то есть, другими словами, он должен совпадать с заглавной буквой, за которой сразу следует его нижний регистр.Но, насколько я понимаю, вы не можете «добавить значение ascii» в обратную ссылку в регулярном выражении.

И бонусные баллы для тех, кто может ответить на этот вопрос - в данном конкретном случае, как известно, длина рассматриваемой строки составляет 10 символов.Можно ли создать регулярное выражение, которое соответствует строкам произвольной длины?

1 Ответ

0 голосов
/ 05 декабря 2018

Вы хотите использовать следующий шаблон с модулем Python regex:

^(?=(\p{L})(\p{L})(\p{L})(\p{L})(\p{L}))(?=.*(?!\1)(?i:\1)(?!\2)(?i:\2)(?!\3)(?i:\3)(?!\4)(?i:\4)(?!\5)(?i:\5)$)

См. Демонстрационную версию regex

Подробности

  • ^ - начало строки
  • (?=(\p{L})(\p{L})(\p{L})(\p{L})(\p{L})) - положительный прогноз с последовательностью из пяти групп захвата, которые захватывают первые пять букв по отдельности
  • (?=.*(?!\1)(?i:\1)(?!\2)(?i:\2)(?!\3)(?i:\3)(?!\4)(?i:\4)(?!\5)(?i:\5)$) - позитивный взгляд, который гарантирует, что в конце строки есть 5 букв, которые совпадают с буквами, захваченными в начале, но имеют другой регистр.

Вкратцепервый (\p{L}) в первом взгляде захватывает первый a в abcdeABCDE, а затем, внутри второго взгляда, (?!\1)(?i:\1) гарантирует, что пятый символ с конца одинаков (при включенном режиме без учета регистра)и (?!\1) отрицательный взгляд, убедитесь, что эта буква не идентична захваченной.

Модуль re не поддерживает встроенные группы модификаторов, поэтому это выражение не будет работать с этим модулем.

Python regex демонстрационный модуль :

import regex
strs = ['abcdeABCDE', 'abcdEABCDe', 'zYxWvZyXwV', 'abcdeABCDZ', 'abcdeABCDe']
rx = r'^(?=(\p{L})(\p{L})(\p{L})(\p{L})(\p{L}))(?=.*(?!\1)(?i:\1)(?!\2)(?i:\2)(?!\3)(?i:\3)(?!\4)(?i:\4)(?!\5)(?i:\5)$)'
for s in strs:
    print("Testing {}...".format(s))
    if regex.search(rx, s):
        print("Matched")

Вывод:

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