compile()วิธีการที่มักจะเรียกว่าในบางจุด; เป็นวิธีเดียวในการสร้างวัตถุ Pattern คำถามก็คือทำไมคุณถึงเรียกมันอย่างโจ่งแจ้ง ? เหตุผลประการหนึ่งคือคุณต้องการการอ้างอิงถึงวัตถุ Matcher เพื่อให้คุณสามารถใช้วิธีการต่างๆเช่นgroup(int)ดึงเนื้อหาของการจับกลุ่ม วิธีเดียวที่จะได้รับ ahold ของวัตถุ Matcher คือโดยใช้matcher()วิธีการของวัตถุ Pattern และวิธีเดียวที่จะได้รับ ahold ของวัตถุ Pattern คือผ่านcompile()วิธีการ จากนั้นมีfind()วิธีการที่ไม่เหมือนmatches()กันคือไม่ซ้ำกันในคลาส String หรือ Pattern
อีกเหตุผลหนึ่งคือหลีกเลี่ยงการสร้างวัตถุ Pattern เดียวกันซ้ำแล้วซ้ำเล่า ทุกครั้งที่คุณใช้หนึ่งในวิธีที่ขับเคลื่อนด้วย regex ใน String (หรือmatches()วิธีการแบบคงที่ใน Pattern) ระบบจะสร้างรูปแบบใหม่และ Matcher ใหม่ ดังนั้นข้อมูลโค้ดนี้:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
... เทียบเท่ากับสิ่งนี้:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
เห็นได้ชัดว่านั่นเป็นการทำงานที่ไม่จำเป็นมากมาย ในความเป็นจริงอาจใช้เวลาในการคอมไพล์ regex และสร้างอินสแตนซ์อ็อบเจ็กต์ Pattern นานกว่าที่จะทำการจับคู่จริงได้อย่างง่ายดาย ดังนั้นจึงเป็นเรื่องที่สมเหตุสมผลที่จะดึงขั้นตอนนั้นออกจากวง คุณสามารถสร้าง Matcher ล่วงหน้าได้เช่นกันแม้ว่าจะไม่แพงมากนัก:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
if ( m.reset(s).matches() ) {
doSomething();
}
}
หากคุณคุ้นเคยกับ regexes .NET คุณอาจสงสัยว่าcompile()เมธอดของ Java เกี่ยวข้องกับRegexOptions.Compiledตัวปรับแต่งของ. NET หรือไม่ คำตอบคือไม่ Pattern.compile()วิธีการของ Java นั้นเทียบเท่ากับตัวสร้าง Regex ของ. NET เท่านั้น เมื่อคุณระบุCompiledตัวเลือก:
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
... มันรวบรวม regex โดยตรงกับโค้ด CIL byte ทำให้ทำงานได้เร็วขึ้นมาก แต่มีต้นทุนสูงในการประมวลผลล่วงหน้าและการใช้หน่วยความจำ - คิดว่ามันเป็นสเตียรอยด์สำหรับ regexes Java ไม่มีทางเทียบเท่า มีความแตกต่างระหว่างรูปแบบที่สร้างขึ้นอยู่เบื้องหลังโดยไม่ได้และคนที่คุณสร้างอย่างชัดเจนด้วยString#matches(String)Pattern#compile(String)
(แก้ไข: แต่เดิมฉันบอกว่าอ็อบเจ็กต์. NET Regex ทั้งหมดถูกแคชซึ่งไม่ถูกต้องตั้งแต่. NET 2.0 การแคชอัตโนมัติจะเกิดขึ้นเฉพาะกับวิธีการแบบคงที่เช่นRegex.Matches()ไม่ใช่เมื่อคุณเรียกตัวสร้าง Regex โดยตรงอ้างอิง )