compile()
Yöntem her zaman bir noktada denir; bir Pattern nesnesi oluşturmanın tek yolu budur. Öyleyse soru gerçekten, neden açıkça adlandırmalısınız ? Bunun nedenlerinden biri group(int)
, yakalama gruplarının içeriğini almak gibi yöntemlerini kullanabilmeniz için Matcher nesnesine bir referansa ihtiyacınız olmasıdır . Matcher nesnesine ulaşmanın tek yolu, Pattern nesnesinin matcher()
yöntemini kullanmaktır ve Pattern nesnesine ulaşmanın tek yolu compile()
yöntemdir. Ardından , String veya Pattern sınıflarında find()
aksine matches()
, yinelenmeyen bir yöntem var .
Diğer neden, aynı Pattern nesnesini tekrar tekrar oluşturmaktan kaçınmaktır. String'de regex destekli yöntemlerden birini (veya matches()
Pattern'deki statik yöntemi) her kullandığınızda, yeni bir Desen ve yeni bir Eşleştirici oluşturur. Yani bu kod pasajı:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
... tam olarak buna eşdeğerdir:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
Açıkçası, bu çok fazla gereksiz iş yapıyor. Aslında, regex'i derlemek ve Pattern nesnesini somutlaştırmak, gerçek bir eşleştirme yapmaktan kolayca daha uzun sürebilir. Bu nedenle, genellikle bu adımı döngüden çıkarmak mantıklıdır. Eşleştiriciyi, neredeyse o kadar pahalı olmasalar da, önceden de oluşturabilirsiniz:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
if ( m.reset(s).matches() ) {
doSomething();
}
}
.NET regexlerine aşina iseniz, Java compile()
yönteminin .NET'in RegexOptions.Compiled
değiştiricisiyle ilişkili olup olmadığını merak ediyor olabilirsiniz ; cevap hayır. Java'nın Pattern.compile()
yöntemi yalnızca .NET'in Regex yapıcısına eşdeğerdir. Compiled
Seçeneği belirttiğinizde :
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
... regex'i doğrudan CIL bayt koduna derler ve çok daha hızlı çalışmasına izin verir, ancak ön işlem ve bellek kullanımında önemli bir maliyetle - bunu regexler için steroidler olarak düşünün. Java'nın eşdeğeri yoktur; Perde arkasında yaratılan bir Kalıp String#matches(String)
ile açıkça oluşturduğunuz bir Kalıp arasında hiçbir fark yoktur Pattern#compile(String)
.
(DÜZENLEME: Başlangıçta tüm .NET Regex nesnelerinin önbelleğe alındığını söyledim, bu yanlış. .NET 2.0'dan beri, otomatik önbelleğe alma, Regex.Matches()
doğrudan bir Regex yapıcısını çağırdığınızda değil, yalnızca statik yöntemlerle gerçekleşir . Ref )