Java matchesumieszcza ^ na początku i $ na końcu wyrażeń regularnych. Więc matches("[a-z]")faktycznie szuka zamiast tego / ^ [az] $ /.
Robino
Tak @Robino, masz całkowitą rację.
Mihir
1
Z pewnością, jeśli spodziewasz matchessię szukać jakiegokolwiek wystąpienia [a-z], to powinno pasować do nich wszystkich? Nie spodziewałbym matchessię, że sprawdzę każdą postać indywidualnie w odniesieniu do wyrażenia regularnego.
PhilHibbs
@Robino: Gdzie ta funkcjonalność jest opisana / udokumentowana?
Toru
@Toru Na stronie dokumentacji java dla String.Matches - gdzie jeszcze? Przypadkowe wyrażenie Google „ciąg java pasuje do dokumentacji” ujawnia w górnym wyniku wyrażenie „str.matches (regex) daje dokładnie taki sam wynik jak wyrażenie”. Ważnym słowem jest „dokładnie”.
Robino
Odpowiedzi:
323
Witamy w źle nazwanej .matches()metodzie Javy ... Próbuje i dopasowuje WSZYSTKIE dane wejściowe. Niestety inne języki poszły w jej ślady :(
Jeśli chcesz sprawdzić, czy wyrażenie regularne pasuje do tekstu wejściowego, użyj a Pattern, a Matcheroraz .find()metody dopasowania:
Pattern p =Pattern.compile("[a-z]");Matcher m = p.matcher(inputstring);if(m.find())// match
Jeśli naprawdę chcesz sprawdzić, czy dane wejściowe mają tylko małe litery, możesz użyć .matches(), ale musisz dopasować jeden lub więcej znaków: dołącz a +do swojej klasy postaci, jak w [a-z]+. Lub użyj ^[a-z]+$i .find().
znajduję setki niekompletnych samouczków w Internecie. Nie udało się znaleźć dobrego. Masz jakieś sugestie?
John
Dzięki @fge za wyjaśnienie .matches(). Może wiesz, dlaczego .find()w tym przykładzie działa tak wolno ?
Konstantin Konopko
3
Co masz na myśli mówiąc, że inne języki idą w ich ślady ? Z tego, co wiem, tylko C ++ ma równoważny zestaw metod - regex_searchi regex_match. W Pythonie re.matchtylko zakotwicza dopasowanie na początku łańcucha (tak jakby było \Apattern), a Python 3.x ma fajną .fullmatch()metodę. W JS, Go, PHP i .NET nie ma metod regex, które niejawnie zakotwiczają dopasowanie. ElasticSearch, XML Schema i HTML5 / Validators Wzorce angluar są zawsze domyślnie zakotwiczone. W Swift / Objective C istnieje sposób na zakotwiczenie wzoru na początku za pomocą opcji.
Wiktor Stribiżew
Czy jest na to sposób oneliner?
Kardynał - Przywróć Monikę
44
[a-z]dopasowuje pojedynczy znak od a do z. Tak więc, jeśli twój ciąg "d"byłby na przykład tylko, to zostałby dopasowany i wydrukowany.
Musisz zmienić swoje wyrażenie regularne na, [a-z]+aby dopasować jeden lub więcej znaków.
Oczywiście pasuje do pojedynczego znaku, to właśnie robi to wyrażenie regularne! Nie jest jednak jasne (i nie powinno tak być!) To fakt, że java umieszcza przedrostek ^i sufiks $wokół podanego wyrażenia regularnego, zmieniając je niechcianie i tworząc dziwne błędy. Nie powinni tego robić, ponieważ nie tak rozumiano pierwotne wyrażenie regularne.
klaar
28
String.matcheszwraca, czy cały ciąg pasuje do wyrażenia regularnego, a nie tylko do dowolnego podłańcucha.
matches
umieszcza ^ na początku i $ na końcu wyrażeń regularnych. Więcmatches("[a-z]")
faktycznie szuka zamiast tego / ^ [az] $ /.matches
się szukać jakiegokolwiek wystąpienia[a-z]
, to powinno pasować do nich wszystkich? Nie spodziewałbymmatches
się, że sprawdzę każdą postać indywidualnie w odniesieniu do wyrażenia regularnego.Odpowiedzi:
Witamy w źle nazwanej
.matches()
metodzie Javy ... Próbuje i dopasowuje WSZYSTKIE dane wejściowe. Niestety inne języki poszły w jej ślady :(Jeśli chcesz sprawdzić, czy wyrażenie regularne pasuje do tekstu wejściowego, użyj a
Pattern
, aMatcher
oraz.find()
metody dopasowania:Jeśli naprawdę chcesz sprawdzić, czy dane wejściowe mają tylko małe litery, możesz użyć
.matches()
, ale musisz dopasować jeden lub więcej znaków: dołącz a+
do swojej klasy postaci, jak w[a-z]+
. Lub użyj^[a-z]+$
i.find()
.źródło
.matches()
. Może wiesz, dlaczego.find()
w tym przykładzie działa tak wolno ?regex_search
iregex_match
. W Pythoniere.match
tylko zakotwicza dopasowanie na początku łańcucha (tak jakby było\Apattern
), a Python 3.x ma fajną.fullmatch()
metodę. W JS, Go, PHP i .NET nie ma metod regex, które niejawnie zakotwiczają dopasowanie. ElasticSearch, XML Schema i HTML5 / Validators Wzorce angluar są zawsze domyślnie zakotwiczone. W Swift / Objective C istnieje sposób na zakotwiczenie wzoru na początku za pomocą opcji.[a-z]
dopasowuje pojedynczy znak od a do z. Tak więc, jeśli twój ciąg"d"
byłby na przykład tylko, to zostałby dopasowany i wydrukowany.Musisz zmienić swoje wyrażenie regularne na,
[a-z]+
aby dopasować jeden lub więcej znaków.źródło
^
i sufiks$
wokół podanego wyrażenia regularnego, zmieniając je niechcianie i tworząc dziwne błędy. Nie powinni tego robić, ponieważ nie tak rozumiano pierwotne wyrażenie regularne.String.matches
zwraca, czy cały ciąg pasuje do wyrażenia regularnego, a nie tylko do dowolnego podłańcucha.źródło
implementacja wyrażeń regularnych w języku java próbuje dopasować cały ciąg
różni się od wyrażeń regularnych perla, które próbują znaleźć pasującą część
jeśli chcesz znaleźć ciąg zawierający tylko małe litery, użyj wzorca
[a-z]+
jeśli chcesz znaleźć ciąg zawierający co najmniej jedną małą literę, użyj wzorca
.*[a-z].*
źródło
Używany
źródło
Kiedyś napotkałem ten sam problem:
Powyższe zawiodło!
Powyższe działało ze wzorem w obrębie
(
i)
.źródło
Twoje wyrażenie regularne
[a-z]
nie pasuje,dkoe
ponieważ pasuje tylko do Ciągów o długości 1. Użyj czegoś w rodzaju[a-z]+
.źródło
musisz umieścić co najmniej przechwycenie
()
we wzorcu, aby dopasować i poprawić wzór w następujący sposób:źródło
matches
nie ma żadnego wyjścia.Aby wzorzec nie uwzględniał wielkości liter, wykonaj:
źródło