2011-07-19 8 views
9

Jestem nieco zaskoczony konkretnym wyrażeń regularnych, który wydaje się prosty.Prosty Regeks, dopasuj dowolny ciąg z co najmniej jednym łącznikiem

Dopasowanie musi być ciągiem zawierającym tylko a-z, A-Z, 0-9 i musi mieć co najmniej jedno wystąpienie znaku "-" w dowolnym miejscu ciągu.

Mam [a-zA-Z0-9-]+, ale problem polega na tym, że dopasuje się również do tych bez znaku "-".

ABC123-ABC //should match 

ABC123ABC //shouldn't match. 

Odpowiedz

19

To powinno działać:

^([a-zA-Z0-9]*-[a-zA-Z0-9]*)+$ 

Także jeśli chcesz mieć dokładnie 135 myślnikami:

^([a-zA-Z0-9]*-[a-zA-Z0-9]*){135}$ 

lub jeśli chcesz mieć co najmniej 23 myślniki ale nie więcej niż 54 łączniki:

^([a-zA-Z0-9]*-[a-zA-Z0-9]*){23,54}$ 

Otrzymujesz punkt :)

+0

Dzięki, rób rzeczy s dostaniesz się naprawdę długo, jeśli potrzebujesz n liczby myślników? – maxp

+1

Po prostu FYI: pierwsze wyrażenie w tym poście ('^ [a-zA-Z0-9] * - [a-zA-Z0-9] * $') dopasowuje _exactly_ jeden łącznik, więc jeśli chcesz __ co najmniej jeden łącznik (jak podano w oryginalnym wpisie), powinieneś go zawinąć jak inne przykłady i dodać ** + **: '^ ([a-zA-Z0-9] * - [a-zA-Z0-9] *) + $ ' –

+0

To będzie nawet pasować do łańcucha, który ma tylko -. Co jeśli zawsze trzeba będzie zawijać między alfanumami? Nie używamy ([a-zA-Z0-9] + - [a-zA-Z0 -9] +) Próbowałem, ale nie pasuje poprawnie. Czy ta część pasma po dopasowaniu nie będzie brana pod uwagę po raz drugi? Przepraszam, jestem nowy w regex i zdezorientowany. –

2

rozwiązanie Piotra: (^([a-zA-Z0-9]*-[a-zA-Z0-9]*)+$) wykonuje dobrze, gdy dany ciąg, który pasuje. Jednakże wyrażenie to przeżywa Catastrophic Backtracking gdy przedstawiane z ciągiem niedopasowanych takich jak:

aa-aa-aa-aa-aa-aa-aa-aa-aa-aa-aa-aa%

Oto wyrażenia regularne które pozwalają uniknąć tego problemu:

^[a-zA-Z0-9]*-[-a-zA-Z0-9]*$ # Match one or more -

^([a-zA-Z0-9]*-){5}[a-zA-Z0-9]*$ # Match exactly 5 -

^([a-zA-Z0-9]*-){1,5}[a-zA-Z0-9]*$ # Match from 1 to 5 -

Powiązane problemy