Нужна помощь, чтобы найти правильный шаблон соответствия регулярным выражениям

#python #regex #uppercase

#python #регулярное выражение #верхний регистр

Вопрос:

Я не могу найти рабочее регулярное выражение в python для разделения этих строк:

 CAT One | desired: CAT

DOG SILVER FOX Two | desired: DOG SILVER FOX

KING KONG | desired: KING KONG

P'OT THEN Mark First | desired P'OT THEN
  

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

У меня могли быть {1,n} слова в верхнем регистре и слова с {0,n} заглавной буквы.

Мои регулярные выражения были слишком странными, я улавливаю всю строку или только одно слово в верхнем регистре..

Комментарии:

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

Ответ №1:

 import re

lines = [
    "CAT One",
    "DOG SILVER FOX Two",
    " KING KONG ",
    "P'OT THEN Mark First",
    "FOO-BAR Second FISH",
    "horsE YELLOW thirD BLUE",
    ]

for line in lines:
    print re.findall(r'b[A-Z] (?:W*[A-Z] )*b', line)
  

Вывод:

 ['CAT']
['DOG SILVER FOX']
['KING KONG']
["P'OT THEN"]
['FOO-BAR', 'FISH']
['YELLOW', 'BLUE']
  

Объяснение:

b[A-Z] означает: сопоставьте одну или несколько заглавных букв, но только в начале слова. Это будет соответствовать «ЖЕЛТОМУ», но не «E» в «horsE».

W*[A-Z] означает: сопоставьте ноль или более символов, не являющихся словами, за которыми следует одна или несколько заглавных букв. Это будет соответствовать «‘OT» или «-BAR» или «KONG».

(?:W*[A-Z] )*b означает: создайте (не захватывающую) группу, которая соответствует нулю или более раз, но только в конце слова. Это будет соответствовать «SILVER FOX», но не «T», который следует за ним.

Комментарии:

1. спасибо, это сработало. что такое ?: ? не могли бы вы немного объяснить регулярное выражение?

2. @avastreg. Рад, что вы нашли это полезным. Я добавил объяснение к своему ответу.

Ответ №2:

Решение без регулярных выражений:

 tests = """
CAT One
DOG SILVER FOX Two
KING KONG
P'OT THEN Mark First
""".splitlines()

isAllUppercase = lambda s: all(c.upper() == c for c in s)

from itertools import takewhile

for t in tests:
    print t
    print ' '.join(takewhile(isAllUppercase,t.split()))
    print
  

Дает:

 CAT One
CAT

DOG SILVER FOX Two
DOG SILVER FOX

KING KONG
KING KONG

P'OT THEN Mark First
P'OT THEN
  

Комментарии:

1. да, я сделал это тем временем.. но я хочу знать, как это сделать, на всякий случай, если невозможно найти альтернативу

Ответ №3:

 [^a-z ](?![a-z])| (?![A-Z]?[a-z])
  

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

или

за пробелом не следует (необязательно прописная буква) и строчная буква.

Неясно, следует ли вам предварительно откладывать a ^ , потому что слова в верхнем регистре всегда являются первыми.

 ^[^a-z ](?![a-z])| (?![A-Z]?[a-z])
  

(здесь мы игнорируем случай пробела в качестве первого символа. так что нет (space)KING KONG . Если вы хотите включить его, поставьте a ^ после | , например ^ (?![A-Z]?[a-z]) )

Ответ №4:

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

 [A-Z']  ?[A-Z'] ?(?![a-z])
  

[A-Z'] это диапазон символов, которые вы сопоставляете, если вам нужно больше знаков препинания, ' просто добавьте их в этот диапазон.