Регулярное совпадение, только если подстрока встречается один раз - PullRequest
0 голосов
/ 24 мая 2019

У меня есть ввод одной строки, которая выглядит как

foo[TAG1][TAG2]

где TAG1 и TAG2 - это уникальный предопределенный набор слов, и каждое из них должно использоваться только один раз.

Например, TAG1 = {A, B, C} и TAG2 = {1, 2, 3}.

Должно совпадать следующее:

  • foo[A][1]
  • foo[B][3]
  • foo[2][B]

Не должно совпадать следующее:

  • foo[A][A]
  • foo[1][3]
  • foo[C][B]
  • foo[C]
  • foo[23]

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Импорт:

import re

Входные данные:

rules = {
    "TAG1": {"A", "B", "C"},
    "TAG2": {"1", "2", "3"}
}

template = "foo[TAG1][TAG2]"

test_strings = ["foo[A][1]", "foo[B][3]", "foo[2][B]", "foo[A][A]", "foo[1][3]", "foo[C][B]", "foo[C]", "foo[23]"]

Код:

compiled_template = template[:]

for k, v in rules.items():
    if k in template:
        compiled_template = compiled_template.replace(f"[{k}]", f"(?=.*\[({'|'.join(v)})\])")

for string in test_strings:
    if re.match(compiled_template, string):
        print(string)

Выход:

foo[A][1]
foo[B][3]
foo[2][B]
0 голосов
/ 24 мая 2019

Попробуйте использовать следующий шаблон:

r'(foo(?:(?:\[[A-Z]\]\[\d+\])|(?:\[\d+\]\[[A-Z]\])))'

См. демо


Разбивка:

  • 1-я группа захвата (foo(?:(?:\[[A-Z]\]\[\d+\])|(?:\[\d+\]\[[A-Z]\])))
    • foo соответствует символам foo буквально (с учетом регистра)
    • Группа без захвата (?:(?:\[[A-Z]\]\[\d+\])|(?:\[\d+\]\[[A-Z]\]))
      • 1-я альтернатива (?:\[[A-Z]\]\[\d+\])
        • Группа без захвата (?:\[[A-Z]\]\[\d+\]) \[ соответствует символу [буквально (с учетом регистра)
          • Соответствует одному символу, представленному в списке ниже [A-Z]
          • A-Z один символ в диапазоне между A (индекс 65) и Z (индекс 90) (с учетом регистра)
          • ] соответствует символу] буквально (с учетом регистра)
          • [соответствует символу [буквально (с учетом регистра)
          • \ d + соответствует цифре (равной [0-9])
          • ] соответствует символу] буквально (с учетом регистра)
      • 2-ой вариант (?:\[\d+\]\[[A-Z]\])
        • Группа без захвата (?:\[\d+\]\[[A-Z]\])
          • \[ соответствует символу [буквально (с учетом регистра)
          • \d+ соответствует цифре (равно [0-9])
          • \] соответствует символу] буквально (с учетом регистра)
          • \[ соответствует символу [буквально (с учетом регистра)
          • Соответствует одному символу, представленному в списке ниже [A-Z]
          • \] соответствует символу] буквально (с учетом регистра)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...