2012-04-29 7 views
5

Przetwarzam tekst będący wielokrotnym powtórzeniem prostego wzoru. Tekst jest w formacie scenariusz do gry, podobnie jak to:Wyrażenie regularne, aby dopasować wszystkie znaki do następnego dopasowania.

SAMPSON 
I mean, an we be in choler, we'll draw. 

GREGORY 
Ay, while you live, draw your neck out o' the collar. 

obecnie używam wzorzec ([A-Z0-9\s]+)\s*\:?\s*[\r\n](.+)[\r\n]{2}, które działa prawidłowo (wyjaśnienie poniżej) z wyjątkiem gdy mowy bohatera ma podziały wiersza w nim . Kiedy tak się dzieje, imię postaci zostaje przechwycone z powodzeniem, ale przechwycony zostaje tylko pierwszy wiersz mowy.

Włączenie trybu jednowierszowego (aby uwzględnić podziały wierszy w .) tworzy tylko jeden gigantyczny mecz.

Jak mogę powiedzieć, aby (.+) zatrzymał się po znalezieniu następnej nazwy postaci i zakończeniu meczu?
Powtarzam poszczególne pojedynki (JavaScript), więc nazwa musi być dostępna do następnego dopasowania.

Idealnie byłoby, aby dopasować wszystkie znaki, aż cały wzór zostanie powtórzony.


Wzór wyjaśnił:

Pierwsze mecze grupowe imię bohatera (pozwalającą litery, cyfry i spacje), (ze spływu okrężnicy i spacje opcjonalnie).
Druga grupa (mowa postaci) rozpoczyna się w nowym wierszu i przechwytuje dowolne znaki (z wyjątkiem problemów, linii i znaków po nich).
Wzór kończy się (i rozpoczyna się od nowa) po pustym wierszu.

+0

trzeba jednoznacznie zdefiniować, jak określa, gdzie kolejna nazwa zaczyna się, zanim będzie można nakaz e regex, aby go dopasować. Czy to jedno słowo, a następnie dwukropek w linii? Czy to spowoduje niepoprawne dopasowanie? – mellamokb

+0

@mellamokb Zapomniałem dołączyć ostatnią część wzorca, który szuka pustej linii. Mecz rozpoczyna się od imienia postaci (wszystkie kapitaliki w osobnej linii) i kończy po pustym wierszu po przemówieniu. – Nathan

+0

Wierzę, że brakuje ci dwukropków w przykładowym tekście, wyrażenie regularne nie działa z tym. –

Odpowiedz

0

Dobra, trochę poszperałem i znalazłem coś, co działa. Nie jest super elegancki, ale spełnia swoją rolę.

([A-Z0-9\s]+)\s*\:?\s*[\r\n]((.+[\r\n]?.*)+)[\r\n]{2} 

Zmodyfikowałem ostatnią grupę przechwytywania, aby umożliwić nieskończone powtarzanie dowolnego tekstu, nowej linii i bardziej dowolnego tekstu. Ponieważ dwie linie podziału z rzędu nie są dozwolone, wzór kończy się po przemówieniu.

+0

Chciałem tylko wskazać, że wkleiłem wyrażenie regularne i przykład z twojego pytania do [narzędzia do testowania regex] (http://gskinner.com/RegExr/), a następnie włączono tryb * dotall * (punkty dopasowują newlines), które rozwiązano Twój problem. To dziwne, że nie zadziałało dla ciebie – Hubro

1

Zastanów się nad tym w innym kierunku. Naprawdę chcesz podzielić większe okno dialogowe na dowolną linię zawierającą nazwę. Można to zrobić za pomocą wyrażenia regularnego nadal (wymienić regex z tym, co będzie pasował linię „głośnika”):

results = "Insert script here".split(/^([A-Z]+)$/) 

Na standardom realizacja zgodna, to przykład tekst trafi do tablicy tak:

results[0] = "" 
results[1] = "SAMPSON"  
results[2] = "I mean, an we be in choler, we'll draw.    
" 
results[3] = "GREGORY"  
results[4] = "Ay, while you live, draw your neck out o' the collar. " 

Ograniczeniem jest to, że większość przeglądarek jest tutaj niespotykana. Możesz użyć biblioteki XRegExp, aby uzyskać działanie na wielu platformach.

+0

W moim przypadku użycia podzielenie okien dialogowych na oddzielne wiersze nie ma sensu. Ponieważ program (i użytkownik) wchodzi w interakcję z dialogami jako całością, musiałbym po prostu połączyć je ponownie, aby były przydatne. – Nathan

0

W końcu udało mi się go dopasować tylko do tego, co chciałeś, tj.
- nazwa znaku, umożliwiając whitespaces i okrężnicy
- i ewentualnie multilinii z wierszami, tekst związany z osobą

Trzeba by zrobić findAll za pomocą tego wyrażenia regularnego - to jest wielkość liter:

((?:[A-Z]{2,}\s*:?\s*)+)\s+((?![A-Z]{2,}\s*:?\s*).+?[.?!]\s*)+ 

Objaśnienie:

  • ((?:[A-Z]{2,}\s*:?\s*)+) - pierwsza grupa rejestruje nazwę górną przypadku osoby - to dopasuje „GREGOR”, jak również „MANFRED NAJWIĘKSZY:”
  • \s+ - co najmniej jeden biały znak
    Następnie powtórzyć co najmniej raz:
  • (?![A-Z]{2,}\s*:?\s*) - patrzeć w przyszłość, aby sprawdzić, czy obok tekst nie jest górna sprawa nazwa postaci
  • .+?[.?!]\s* - pasuje do wszystkiego, aż znajdziesz znak, który kończy zdanie [.?!] i ewentualnie odstępy
Powiązane problemy