regex - сопоставлять слова с дефисом только в верхнем регистре - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь сопоставить слова, состоящие из более чем 1 буквы и:: все в верхнем регистре, строчные буквы в верхнем регистре и заглавные буквы в нижнем регистре или содержащие дефис ТОЛЬКО в середине, если все буквы прописные. Это мой код:

s = "ASCII, aSCII, AS-CII, AS-cii"

myset =   set(re.findall(r"\b[a-z]?[A-Z]+\-?[A-Z]{1,}",s))

Out[555]: {'AS', 'AS-CII', 'ASCII', 'aSCII'}

Как видите, "AS" возвращать не следует, поскольку он содержит строчные буквы после дефиса. Как я мог это исправить?

Пробовал это, но в результате ошибка:

myset = set(re.findall(r"\b[a-z]?[A-Z]+\-?[A-Z]+{1,}",s))

  File "<ipython-input-545-7bdc0c902553>"
    myset = set(re.findall(r"\b[a-z]?[A-Z]+\-?[A-Z]+{1,}",s))

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/re.py", line 222, in findall
    return _compile(pattern, flags).findall(string)

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/re.py", line 301, in _compile
    p = sre_compile.compile(pattern, flags)

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/sre_compile.py", line 562, in compile
    p = sre_parse.parse(p, flags)

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/sre_parse.py", line 855, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/sre_parse.py", line 416, in _parse_sub
    not nested and not items))

  File "/home/c1962135/.local/share/virtualenvs/c1962135-9R_1M4TP/lib/python3.6/sre_parse.py", line 619, in _parse
    source.tell() - here + len(this))

error: multiple repeat

Ответы [ 4 ]

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

Вы можете использовать следующее регулярное выражение, которое охватывает крайние случаи, имеющие отношение к слову, которому предшествует или следует дефис (как показано по ссылке ниже):

(?<!\w|(?<=\w)-)(?:[a-zA-Z][A-Z]+|[A-Z]{2,}|[A-Z]+-[A-Z]+)(?!\w|-(?=\w))

Демонстрация Механизм регулярного выражения

Python выполняет следующие операции.

(?<!              # begin a negative lookbehind
  \w              # match word char
  |               # or
  (?<=\w)         # match a word char in a positive lookbehind
  -               # match '-'
)                 # end negative lookbehind
(?:               # begin non-cap grp
  [a-zA-Z][A-Z]+  # match a lc letter then 1+ uc letters
  |               # or
  [A-Z]{2,}       # match 2+ uc letters
  |               # or
  [A-Z]+-[A-Z]+   # match 1+ uc letters, '-', then 1+ uc letters
)                 # end non-cap grp
(?!               # begin negative lookahead
  \w              # match word char
  |               # or
  -               # match '-'
  (?=\w)          # match a word char in a positive lookahead
)                 # end negative lookahead
0 голосов
/ 07 апреля 2020

Вы можете использовать условное выражение :

(...)?(if true than this|else this)

Для вашего случая это может быть

\b([a-z])?(?(1)[A-Z]+|[-A-Z]+[A-Z])(?!-)\b

См. демо на regex101.com .


Разбитое это читает
\b               # a word boundary
([a-z])?         # match a lower case letter if it is there
(?(1)            # if the lower case letter is there, match this branch
    [A-Z]+
|
    [-A-Z]+[A-Z] # else this one
)
(?!-)\b          # do not break at a -, followed by another boundary
0 голосов
/ 07 апреля 2020

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

\b[a-z]*[A-Z]+[\-A-Z]+[A-Z]+\b

Пожалуйста, отметьте здесь https://regex101.com/r/JNC4kN/1/

Но это не удастся, если вы зададите этот тип Например, как ATH-THTH (маленькая буква после дефиса и заглавные буквы) Если вы хотите только UPPER-UPPER, следуйте этому регулярному выражению:

\b[a-z]{0,1}(?<!\-)[A-Z]+\b(?!\-)|\b[A-Z]+\-[A-Z]+\b

, проверьте здесь

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

Вот мы

res = [x[0] for x in re.findall(r"(([a-z]{1}[A-Z]+)|([A-Z]+\-[A-Z]+))",s)]
print(res)
print(set(res))

дает

['aSCII', 'AS-CII']

Скажите мне. Я разделил, чтобы добавить ИЛИ logi c с | между ними.

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