2010-10-21 18 views
5

Niedawno siedziałem z problemem z wyrażeniem regularnym. W końcu rozwiązałem go w inny sposób, bez wyrażeń regularnych, ale nadal chciałbym wiedzieć, jak to robisz:Dopasowywanie dokładnie jednego wystąpienia w ciągu znaków z wyrażeniem regularnym

Problem polegał na tym, że aktualizowałem svn za pomocą automatycznego skryptu i chciałem wykryć konflikty. Robienie tego z lub bez użycia wyrażenia regularnego jest trywialne, ale spowodowało, że zastanawiałem się nad bardziej niejasnym problemem: w jaki sposób dopasowujesz dokładnie JEDNĄ postać w środku pola o stałej długości?

Na przykład, powiedzmy, że chcemy, aby dopasować "C" wewnątrz sześć bajtów szerokim zakresie:

 
"C  " MATCH 
" C " MATCH 
" C C " NO MATCH 
" M " NO MATCH 
"  " NO MATCH 
"C  " NO MATCH (7 characters, not 6) 
" C " NO MATCH (5 characters, not 6) 

Odpowiedz

6

wiem, że to nie jest w porządku, aby odpowiedzieć na własne pytanie, ale ja po prostu połączyły swoje odpowiedzi ... proszę nie płomienia :)

^(?=.{6}$) *C *$

EDIT: Wymiana. Odpowiedź Tomalak w poniższej [C], zwiększa szybkość, z około 4-5% lub tak

^(?=[ C]{6}$) *C *$

+0

+1 Tak, to też jest dobre. Ostateczne '' 'nadal jest niepotrzebne, patrz moja uwaga # 2. * (I nie, nie ma nic złego w odpowiadaniu na twoje własne pytanie.) Nie ma niebezpieczeństwa bycia podpalanym.) * – Tomalak

+0

@tomalak, jeśli usunę ostatnie $, to zawiedzie, gdy coś innego niż C pojawi się po C, a także na wiele wystąpień C – KennethJ

+0

Zobacz moją zmienioną odpowiedź na wstępne spojrzenie, które to naprawi. – Tomalak

5
^(?=[ C]{6}$) *C(?! *C) 

Objaśnienie:

 
^    # start-of-string 
(?=[ C]{6}$) # followed by exactly 6 times " " or "C" and the end-of-string 
*C   # any number of spaces and a "C" 
(?! *C)  # not followed by another C anywhere (negative lookahead) 

Uwagi:

  • Konstrukcja ^(?=…{6}$) może być używana w dowolnym miejscu mierzyć długość łańcucha, ale jeszcze nic nie pasuje.
  • Ponieważ koniec napisu jest już sprawdzony, na końcu wyrażenia regularnego nie trzeba wstawiać $, ale nie zaszkodzi to zrobić.
+0

Nie powinno^C, użytkownik proszony o białym przestrzeni. – testalino

+0

@testalino: Dobra uwaga. To sprawia, że ​​nawet łatwiej. – Tomalak

+0

+1 za niesamowite wykorzystanie widoków z wyprzedzeniem, ciekawy przykład. Jednak mecz kończy się niepowodzeniem na dwóch wystąpieniach C, to naprawia to:^(? =. {6} $) [^ C] *? C (?!. * C) – KennethJ

4
^[^C]*C[^C]*$ 

ale nie będzie to sprawdzić długość łańcucha.

+1

+1 Negatywne klasy postaci są lepsze niż moje poprzedzenie. – Tomalak

+0

Klasy postaci są lepsze. Ale to nie bierze pod uwagę całkowitej długości. Będziesz musiał zrobić coś takiego: '^ (C [^ C] {5} | [^ C] C [^ C] {4} | [^ C] {2} C [^ C] {3} | [^ C] {3} C [^ C] {2} | [^ C] {4} C [^ C] | [^ C] {5} C) $ ' – Gumbo

+0

... ale niestety z drugim wymaganiem (tylko spacje) to już nie działa. Zobacz komentarz @ testalino dotyczący mojej odpowiedzi. – Tomalak

Powiązane problemy