2011-11-18 17 views
10

Jestem okropny w wyrażeniach RegEx i po prostu nie używam ich wystarczająco często, aby zapamiętać składnię między zastosowaniami.Regex do dopasowania, gdy łańcuch jest obecny dwukrotnie

Używam grepWin do przeszukiwania moich plików. Muszę wykonać wyszukiwanie, które spowoduje zwrócenie plików, które mają dany ciąg dwukrotnie.

Tak więc, na przykład, jeśli Szukałem na słowie „jak”, a następnie złożyć jeden nie pasuje:

Witam
jak jesteś dzisiaj?

ale by złożyć dwa:

Witam
jak się dziś czujesz?

Mam się dobrze, jak się masz?

Każdy wie, jak zrobić RegEx, który będzie pasował do tego?

+1

Jeśli szukany ciąg musi być zmienną, nie jest to możliwe w Regeksie. Musiałbyś połączyć to z językiem skryptowym. Jeśli nie musi być zmienna, to wyrażenie regularne wykonałoby: 'jak się masz. * Jak się masz' – Jeff

+1

@Jeff Możliwe jest odesłanie do dopasowanej grupy w wyrażeniu regularnym JavaScript: '/ (abc) \ 1/'dopasowuje' abcabc', ale nie 'abc'. –

+0

Czy musi pasować tylko, jeśli "how" pojawia się _exactly_ dwa razy? Co jeśli pojawi się trzy lub więcej razy? – Wiseguy

Odpowiedz

13

coś takiego (w zależności od języka i konkretnego zadania)

\(how.*){2}\ 

Edit: według @CodeJockey

\^(([^h]|h[^o]|ho[^w])*how([^h]|h[^o]|ho[^w])*){2,2}$\ 

(to bardziej skomplikowane) @CodeJockey: Dzięki dla komentarzy

+3

to dostanie pliki z 'jak' dwa lub więcej razy, ale nie ** wykluczy ** plików z trzema lub więcej wystąpieniami –

+0

tak, masz rację – VMykyt

+1

@CodeJockey Tak też to czytam. Zastanawiałem się, czy pytający dwa razy powiedział to dosłownie. – Wiseguy

1

Jest to znacznie trudniejsze niż początkowo sądziłem byłoby i wymaga zmiennej długości lookbehind, która nie obsługuje grepWin ...

to wyrażenie:

(?<!blah.{0,99999})blah(?=.*?blah)(?!.*blah.*blah) 

był z powodzeniem stosowany w Eclipse, używając „Szukać> plik” dialog wyłączyć pliki z jednym i trzema instancjami blah oraz z plikami o dokładnie dwóch wystąpieniach blah.

Eclipse nie zezwala na zmianę wyglądu na .*, więc zamiast tego użyłem .{0,99999}.

Jest to możliwe za pomocą odpowiedniego narzędzia, ale nie jest to łatwe, aby działało z grepWin (patrz odpowiedź powyżej). Czy możesz użyć innych narzędzi (takich jak Eclipse) i co chcesz później zrobić z plikami?

+0

Jeśli lookbehinds są problem, zrobiłem to tylko z wyprzedzeniem. – Wiseguy

+0

tak - nie zawracałem sobie sobie głowy testowaniem rozwiązania VMykyt w żądanym produkcie i zadziałało (szczególnie bez widocznego zainteresowania z PO). Kiedy początkowo pracowałem nad tym, mój mózg jakoś tymczasowo zatracił ideę kotwicy z początkiem linii lub ciągiem, co powinno umożliwić to bez spojrzenia w tył: D –

+0

@Wiseguy Podoba mi się, że twoje rozwiązanie wykorzystuje całe słowa jednak ... tak czy inaczej, choć nie byłoby to zbyt trudne do dodania, nikt jeszcze nie uwzględnił faktu, że OP może chcieć dopasować tylko pliki z dwoma przykładami, ale pozwolić "haubicy" lub "jakoś" lub nawet "Prysznic" dowolną liczbę razy –

4

Nie wiem, co obsługuje grepWin, ale oto, co wymyśliłem, aby coś dokładnie pasowało dwa razy.

/^((?!how).)*how((?!how).)*how((?!how).)*$/ 

Objaśnienie:

/^    # start of subject 
    ((?!how).)* # any text that does not contain "how" 
    how   # the word "how" 
    ((?!how).)* # any text that does not contain "how" 
    how   # the word "how" 
    ((?!how).)* # any text that does not contain "how" 
$/    # end of subject 

Gwarantuje to, że znajdują się dwa „jak” s, ale teksty między „jak” s, a po obu stronach z nich nie zawierają „jak”.

Oczywiście można zastąpić dowolny ciąg dla "jak" w wyrażeniu.


Jeśli chce "uproszczenia" tylko przez pisanie wyrażenie wyszukiwarki dwukrotnie, można użyć odwołania wstecznego tak:

/^(?:(?!how).)*(how)(?:(?!\1).)*\1(?:(?!\1).)*$/ 

Refiddle with this expression

Objaśnienie:
dodałem ?: aby negatywny tekst z wyprzedzeniem z wyprzedzeniem. Następnie dodałem nawiasy wokół zwykłego how, aby uzyskać przechwytywanie podtytułu (pierwszego i jedynego).

musiałem to „jak” ponownie w pierwszej uprzedzona bo to negatywny uprzedzona (czyli żadnych przechwytywanie byłoby nie zawierać „jak”) oraz przechwycone „jak” nie jest jeszcze zrobione w tym punkcie.

Powiązane problemy