TŁO

Mam scenariusz, w którym muszę ciągle odnajdywać pewne słowa w tekście. Obecnie używam serii wyrażeń regularnych w formacie takim jak ten...

"((^)|(\W))(?<c>Word1)((\W)|($))"

"((^)|(\W))(?<c>NextWord)((\W)|($))"

"((^)|(\W))(?<c>AnotherWord)((\W)|($))"

...

Ta lista obiektów Regex jest przez nie zapętlona z porcją danych, a dopasowania są wyciągane (jedna pętla na jedno wywołanie regex.matches(data))

Zrobiłem wszystko, co w mojej mocy, aby je zoptymalizować, na przykład kompilując je wcześniej.

Jednak lista się wydłuża i postanowiłem zacząć tworzyć większe skompilowane wyrażenia regularne, aby zoptymalizować proces. Jak na przykład...

"((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

Zapewnia to OGROMNĄ poprawę prędkości, jednak jest efekt uboczny, którego nie mogę wymyślić, jak to naprawić.

Gdy słowa znajdują się w danych obok siebie (np. oddzielone spacjami, np. „Słowo1 Następne słowo Inne słowo”), drugie słowo jest pomijane podczas przechwytywania, ponieważ wyrażenie regularne „Słowo1” zawiera również spację na końcu. Dopasowanie, które może wystąpić dla „Następnego słowa”, nie ma już pola wiodącego, ponieważ jest częścią poprzedniego dopasowania.

PYTANIE

Czy każdy może zmienić to wyrażenie regularne (format .net)

Pattern = "((^)|(\W))(?<c>((Word1)|(NextWord)|(AnotherWord)))((\W)|($))"

Do pracy, aby uchwycić wszystkie słowa z poniższej listy za pomocą jednego wywołania „.matches(data)” Gdzie

data = "Word1 NextWord AnotherWord" 

? (bez poświęcania wzrostu wydajności)

wyniki

Pomyślałem, że o tym wspomnę. Po zastosowaniu sugerowanej odpowiedzi/korekty ze spojrzeniem w przód i tyłem, z której teraz wiem jak korzystać :) kod, który właśnie zmodyfikowałem, poprawił się o 347x (0,00347% starej prędkości testowania). Co jest zdecydowanie czymś do zapamiętania, gdy wpadniesz w wiele wyrażeń. Bardzo szczęśliwy.

0
DarrenMB 17 październik 2012, 05:36

2 odpowiedzi

Najlepsza odpowiedź

Możesz chcieć użyć albo kontroli granic, albo lookahead/lookbehind, aby dopasowanie nie zużywało białych znaków, ale je sprawdzało.

Tak jak to:

Pattern = @"\b(Word1|NextWord|AnotherWord)\b"

Lub z spojrzeniem w tył i w przyszłość:

Pattern = @"(?<=\W|^)(Word1|NextWord|AnotherWord)(?=\W|$)"
1
Lucero 17 październik 2012, 05:48

Użyj symbolu \b. Dopasowuje się do granicy słowo/nie słowo.

\b(?((Word1)|(NextWord)|(AnotherWord)))\b
1
Andrew Cooper 17 październik 2012, 05:41