Python podzielony ciąg znaków oparty na wyrażeniu regularnym

115

Jaki jest najlepszy sposób na podzielenie ciągu znaków na przykład "HELLO there HOW are YOU"wielkimi literami (w Pythonie)?

Więc skończyłbym z tablicą taką jak taka: results = ['HELLO there', 'HOW are', 'YOU']


EDYTOWAĆ:

Próbowałem:

p = re.compile("\b[A-Z]{2,}\b")
print p.split(page_text)

Wydaje się jednak, że to nie działa.

Toto
źródło
2
Czego próbowałeś ? - Nie mogłeś znaleźć re.split()?
Gareth Latty
5
Kiedy mówisz, że coś nie działa, wyjaśnij dlaczego. Czy masz wyjątek? (Jeśli tak, opublikuj cały wyjątek). Czy otrzymujesz niewłaściwy wynik?
Gareth Latty

Odpowiedzi:

134

sugeruję

l = re.compile("(?<!^)\s+(?=[A-Z])(?!.\s)").split(s)

Sprawdź to demo .

Ωmega
źródło
5
co się dzieje, gdy nie używasz kompilacji?
Feelsbadman
3
Zgodnie z dokumentacjąwiększość operacji na wyrażeniach regularnych jest dostępnych jako funkcje na poziomie modułu i metody RegexObject. Funkcje są skrótami, które nie wymagają najpierw kompilowania obiektu wyrażenia regularnego, ale pomijają niektóre parametry dostrajające. Możesz użyć re.split(re.split(pattern, string, maxsplit=0, flags=0))jak wspomniano we wcześniej cytowanych dokumentach.
ZaydH
57

Możesz użyć lookahead:

re.split(r'[ ](?=[A-Z]+\b)', input)

Spowoduje to podzielenie w każdej spacji, po której następuje ciąg wielkich liter kończących się granicą słowa.

Zauważ, że nawiasy kwadratowe służą tylko do czytelności i równie dobrze można je pominąć.

Jeśli wystarczy, że pierwsza litera słowa jest wielka (więc jeśli chcesz podzielić również przed Hellonią), stanie się jeszcze łatwiej:

re.split(r'[ ](?=[A-Z])', input)

Teraz dzieli się na każdą spację, po której następuje dowolna wielka litera.

Martin Ender
źródło
1
Jak miałbym to zmienić, re.split(r'[ ](?=[A-Z]+\b)', input)żeby nie znalazło wielkich liter? Np. Nie pasuje do „A”? Próbowałem re.split(r'[ ](?=[A-Z]{2,}+\b)', input). dzięki!
@JamesEggers Masz na myśli, że chcesz wymagać co najmniej dwóch wielkich liter, aby nie rozdzielać słów takich jak I? re.split(r'[ ](?=[A-Z]{2,}\b)', input)powinien to zrobić.
Martin Ender
2
Sugerowałbym przynajmniej, [ ]+a może nawet, \W+złapanie nieco więcej przypadków. Mimo wszystko dobra odpowiedź.
georg
Spróbowałem tego samego podejścia. Jednak posiadanie [ ]nie zadziałało dla mnie. Zamiast tego użyłem \s. Kompletne re.split("\s(?=[A-Z]+\s)", string)
wyrażenie regularne,
0

Twoje pytanie zawiera literał ciągu "\b[A-Z]{2,}\b", ale \bbędzie to oznaczać cofnięcie, ponieważ nie ma modyfikatora r.

Spróbuj: r"\b[A-Z]{2,}\b".

druid62
źródło