Regex tidak berfungsi di String.matches ()


147

Saya punya sepotong kecil kode ini

String[] words = {"{apf","hum_","dkoe","12f"};
for(String s:words)
{
    if(s.matches("[a-z]"))
    {
        System.out.println(s);
    }
}

Seharusnya mencetak

dkoe

tetapi tidak mencetak apa-apa !!


41
Java matchesmenempatkan ^ di awal dan $ di akhir regex untuk Anda. Jadi matches("[a-z]")sebenarnya akan mencari / ^ [az] $ / sebagai gantinya.
Robino

Ya, @Robino Anda memang benar.
Mihir

1
Tentunya, jika Anda berharap matchesuntuk mencari kejadian [a-z], maka itu harus cocok dengan mereka semua? Saya tidak akan berharap matchesuntuk memeriksa setiap karakter secara individual terhadap regex.
PhilHibbs

@Robino: Di manakah fungsionalitas itu dijelaskan / didokumentasikan?
Toru

@ Toru Di halaman java docs untuk String.Matches - di mana lagi? Google biasa "dokumentasi string java cocok" mengungkapkan, di hasil atas, frasa "str.matches (regex) menghasilkan hasil yang persis sama dengan ekspresi". Kata yang penting adalah "tepat".
Robino

Jawaban:


323

Selamat datang di .matches()metode Java yang salah nama ... Mencoba dan cocok dengan SEMUA input. Sayangnya, bahasa lain mengikuti :(

Jika Anda ingin melihat apakah regex cocok dengan teks input, gunakan a Pattern, a Matcherdan .find()metode korek api :

Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
    // match

Jika yang Anda inginkan adalah untuk melihat apakah input hanya memiliki huruf kecil, Anda dapat menggunakan .matches(), tetapi Anda harus mencocokkan satu atau lebih karakter: tambahkan a +ke kelas karakter Anda, seperti pada [a-z]+. Atau gunakan ^[a-z]+$dan .find().


2
saya menemukan 100-an tutorial online tidak lengkap. Tidak dapat menemukan yang bagus. Apakah Anda punya saran?
John

Thanx @fge untuk menjelaskan .matches(). Mungkin Anda tahu mengapa .find()kerjanya sangat lambat dalam contoh ini ?
Konstantin Konopko

3
Apa yang Anda maksud dengan bahasa lain yang mengikuti ? Dari yang saya tahu, hanya C ++ yang memiliki seperangkat metode - regex_searchdan regex_match. Dalam Python, re.matchhanya jangkar yang cocok di awal string (seolah-olah itu \Apattern) dan Python 3.x telah mendapatkan .fullmatch()metode yang bagus . Di JS, Go, PHP, dan .NET, tidak ada metode regex yang mengaitkan pertandingan secara implisit. ElasticSearch, Schema XML dan HTML5 / Validators Pola Angluar selalu berlabuh secara default. Di Swift / Objective C, ada cara untuk menahan pola di awal dengan sebuah opsi.
Wiktor Stribiżew

Apakah ada cara oneliner untuk melakukan ini?
Cardinal - Reinstate Monica

44

[a-z]cocok dengan satu char antara a dan z. Jadi, jika string Anda hanya "d", misalnya, maka itu akan cocok dan dicetak.

Anda perlu mengubah regex Anda [a-z]+agar cocok dengan satu atau lebih karakter.


12
Tentu saja itu cocok dengan satu char, itulah yang regexp lakukan! Namun yang tidak jelas (dan tidak seharusnya demikian!) Adalah bahwa java menempatkan awalan ^dan akhiran di $sekitar regexp yang disediakan, mengubahnya secara tidak diinginkan dan membuat bug aneh. Mereka seharusnya tidak melakukan itu, karena bukan itu maksud regexp awal.
klaar

28

String.matchesmengembalikan apakah seluruh string cocok dengan regex, bukan sembarang substring.


3
Sesuatu yang benar-benar kenyataan yang menyedihkan adalah Anda benar. Saya benar-benar tidak tahu mengapa mereka melakukannya dengan cara ini.
Hola Soy Edu Feliz Navidad

16

Implementasi java dari regex mencoba untuk mencocokkan keseluruhan string

itu berbeda dari perl regex, yang mencoba menemukan bagian yang cocok

jika Anda ingin menemukan string dengan karakter huruf kecil, gunakan pola [a-z]+

jika Anda ingin menemukan string yang mengandung setidaknya satu karakter huruf kecil, gunakan pola .*[a-z].*


info lebih lanjut di sini
ycomp


12

Bekas

String[] words = {"{apf","hum_","dkoe","12f"};
    for(String s:words)
    {
        if(s.matches("[a-z]+"))
        {
            System.out.println(s);
        }
    }

4

Saya pernah menghadapi masalah yang sama:

Pattern ptr = Pattern.compile("^[a-zA-Z][\\']?[a-zA-Z\\s]+$");

Di atas gagal!

Pattern ptr = Pattern.compile("(^[a-zA-Z][\\']?[a-zA-Z\\s]+$)");

Di atas bekerja dengan pola di dalam (dan ).


2

Ekspresi reguler Anda [a-z]tidak cocok dkoekarena hanya cocok dengan string panjang 1. Gunakan sesuatu seperti [a-z]+.


-1

Anda harus memasukkan setidaknya satu tangkapan ()dalam pola untuk dicocokkan, dan memperbaiki pola seperti ini:

String[] words = {"{apf","hum_","dkoe","12f"};
for(String s:words)
{
    if(s.matches("(^[a-z]+$)"))
    {
        System.out.println(s);
    }
}

Kurung tidak mengubah apa pun.
Touniouk

@ Touniouk tanpa tanda kurung matchestidak memiliki output.
MohsenB

-3

Anda dapat membuat pola huruf Anda tidak sensitif dengan melakukan:

Pattern p = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.