JavaRush /จาวาบล็อก /Random-TH /นิพจน์ทั่วไปใน Java ตอนที่ 4

นิพจน์ทั่วไปใน Java ตอนที่ 4

เผยแพร่ในกลุ่ม
เราขอนำเสนอคำแปลคำแนะนำสั้นๆ เกี่ยวกับนิพจน์ทั่วไปในภาษา Java ซึ่งเขียนโดย Jeff Friesen สำหรับเว็บไซต์javaworld เพื่อความสะดวกในการอ่าน เราได้แบ่งบทความออกเป็นหลายส่วน นิพจน์ทั่วไปใน Java ตอนที่ 4 - 1 นิพจน์ทั่วไปใน Java ส่วนที่ 1 นิพจน์ทั่วไปใน Java ส่วนที่ 2 นิพจน์ทั่วไปใน Java ส่วนที่ 3

วิธีการทำงานกับกลุ่มที่ถูกจับ

ซอร์สโค้ดของแอปพลิเค ชันมี การRegexDemoเรียกเมธอด m.group()วิธีนี้group()เป็นหนึ่งในหลายวิธีของชั้นเรียนMatcherที่มุ่งทำงานกับกลุ่มที่ถูกจับ:
  • วิธีการint groupCount()ส่งกลับจำนวนของกลุ่มที่บันทึกในรูปแบบตัวแก้ไข หมายเลขนี้ไม่ได้คำนึงถึงกลุ่มการจับพิเศษหมายเลข 0 ซึ่งสอดคล้องกับรูปแบบโดยรวม

  • วิธีการString group()ส่งกลับอักขระของการจับคู่ก่อนหน้าที่พบ หากต้องการรายงานการค้นหาสตริงว่างที่สำเร็จ เมธอดนี้จะส่งคืนสตริงว่าง หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการนี้String group(int group)คล้ายกับวิธีก่อนหน้า ยกเว้นว่าจะส่งคืนอักขระของรายการที่ตรงกันก่อนหน้านี้ ซึ่งบันทึกโดยหมายเลขกลุ่มที่ระบุโดยgroupพารามิเตอร์ โปรดทราบว่านี่group(0)เทียบเท่าgroup()กับ หากเทมเพลตไม่มีกลุ่มที่บันทึกไว้ตามหมายเลขที่กำหนด วิธีการจะส่งข้อIndexOutOfBoundsExceptionยกเว้น หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการString group(String name)ส่งกลับอักขระของการจับคู่ก่อนหน้าที่พบซึ่งบันทึกโดยกลุ่มชื่อ หากชื่อกลุ่มที่บันทึกไม่อยู่ในเทมเพลต ข้อยกเว้นจะถูกส่งออกIllegalArgumentExceptionไป หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้groupCount()และ วิธีการ group(int group):
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abc");
m.find();
System.out.println(m.groupCount());
for (int i = 0; i <= m.groupCount(); i++)
System.out.println(i + ": " + m.group(i));
ผลการดำเนินการ:
3
0: abc
1: abc
2: bc
3: c
นิพจน์ทั่วไปใน Java ตอนที่ 4 - 2

วิธีการกำหนดตำแหน่งการแข่งขัน

คลาสนี้Matcherมีหลายวิธีที่จะส่งคืนตำแหน่งเริ่มต้นและจุดสิ้นสุดของการแข่งขัน:
  • วิธีการint start()ส่งกลับตำแหน่งเริ่มต้นของการแข่งขันครั้งก่อนที่พบ หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการนี้คล้ายint start(int group)กับวิธีก่อนหน้า แต่จะส่งคืนตำแหน่งเริ่มต้นของรายการที่ตรงกันก่อนหน้านี้ซึ่งพบสำหรับกลุ่มที่มีการระบุหมายเลขโดยพารามิเตอร์ groupหากเทมเพลตไม่มีกลุ่มที่บันทึกไว้ตามหมายเลขที่กำหนด วิธีการจะส่งข้อIndexOutOfBoundsExceptionยกเว้น หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการนี้int start(String name)คล้ายกับวิธีก่อนหน้า แต่จะส่งคืนตำแหน่งเริ่มต้นของรายการที่ตรงกันก่อนหน้าซึ่งพบสำหรับกลุ่มที่เรียกnameว่า หากกลุ่มที่บันทึกnameไม่อยู่ในเทมเพลต จะมีข้อยกเว้นเกิดIllegalArgumentExceptionขึ้น หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • เมธอดint end()ส่งคืนตำแหน่งของอักขระตัวสุดท้ายของการจับคู่ก่อนหน้าที่พบบวก 1 หากตัวจับคู่ยังไม่ได้ดำเนินการจับคู่หรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการนี้คล้ายint end(int group)กับวิธีก่อนหน้า แต่จะส่งคืนตำแหน่งสิ้นสุดของการจับคู่ก่อนหน้าซึ่งพบสำหรับกลุ่มที่มีการระบุหมายเลขโดยพารามิเตอร์ groupหากเทมเพลตไม่มีกลุ่มที่บันทึกไว้ตามหมายเลขที่กำหนด วิธีการจะส่งข้อIndexOutOfBoundsExceptionยกเว้น หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

  • วิธีการนี้int end(String name)คล้ายกับวิธีก่อนหน้า แต่จะส่งคืนตำแหน่งสิ้นสุดของรายการที่ตรงกันก่อนหน้าซึ่งพบสำหรับกลุ่มที่เรียกnameว่า หากกลุ่มที่บันทึกnameไม่อยู่ในเทมเพลต จะมีข้อยกเว้นเกิดIllegalArgumentExceptionขึ้น หากตัวแก้ไขยังไม่ได้ดำเนินการค้นหาหรือการดำเนินการค้นหาก่อนหน้านี้ล้มเหลว ข้อยกเว้นจะถูกส่งออกIllegalStateExceptionไป

ตัวอย่างต่อไปนี้สาธิตวิธีการระบุตำแหน่งการจับคู่สองวิธีที่แสดงตำแหน่งการจับคู่เริ่มต้น/สิ้นสุดสำหรับกลุ่มการจับหมายเลข 2:
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abcabcabc");
while (m.find())
{
   System.out.println("Найдено " + m.group(2));
   System.out.println("  начинается с позиции " + m.start(2) +
                      " и заканчивается на позиции " + (m.end(2) - 1));
   System.out.println();
}
ผลลัพธ์ของตัวอย่างนี้มีดังต่อไปนี้:
Найдено bc
начинается с позиции 1 и заканчивается на позиции 2
Найдено bc
начинается с позиции 4 и заканчивается на позиции 5
Найдено bc
начинается с позиции 7 и заканчивается на позиции 8

วิธีการของคลาส PatternSyntaxException

อินสแตนซ์ของคลาสPatternSyntaxExceptionอธิบายข้อผิดพลาดทางไวยากรณ์ในนิพจน์ทั่วไป โยนข้อยกเว้นดังกล่าวจากวิธีการcompile()และmatches()คลาสPatternและถูกสร้างขึ้นผ่านตัวสร้างต่อไปนี้: PatternSyntaxException(String desc, String regex, int index) ตัวสร้างนี้เก็บคำอธิบายที่ระบุ ( desc) นิพจน์ทั่วไป ( regex) และตำแหน่งที่เกิดข้อผิดพลาดทางไวยากรณ์ หากไม่ทราบตำแหน่งของข้อผิดพลาดทางไวยากรณ์ ค่าindexจะถูกตั้ง ค่า -1เป็น เป็นไปได้มากว่าคุณไม่จำเป็นต้องสร้างอินสแตนซ์ของไฟล์PatternSyntaxException. อย่างไรก็ตาม คุณจะต้องแยกค่าข้างต้นเมื่อสร้างข้อความแสดงข้อผิดพลาดที่จัดรูปแบบ เมื่อต้องการทำเช่นนี้ คุณสามารถใช้วิธีการต่อไปนี้:
  • วิธีการString getDescription()ส่งกลับคำอธิบายของข้อผิดพลาดทางไวยากรณ์
  • วิธีการint getIndex()ส่งคืนตำแหน่งที่เกิดข้อผิดพลาด หรือ -1 หากไม่ทราบตำแหน่ง
  • วิธีการString getPattern()ส่งกลับนิพจน์ทั่วไปที่ไม่ถูกต้อง
นอกจากนี้ วิธีการที่สืบทอดมาString getMessage()จะส่งคืนสตริงหลายบรรทัดด้วยค่าที่ส่งคืนจากวิธีก่อนหน้า พร้อมด้วยการแสดงภาพว่าเกิดข้อผิดพลาดทางไวยากรณ์ที่ใดในเทมเพลต ข้อผิดพลาดทางไวยากรณ์คืออะไร? ตัวอย่าง: java RegexDemo (?itree Treehouse ในกรณีนี้ เราลืมระบุเมตาอักขระวงเล็บปิด ( )) ในนิพจน์แฟล็กที่ซ้อนกัน นี่คือผลลัพธ์จากข้อผิดพลาดนี้:
regex = (?itree
input = Treehouse
Неправильное регулярное выражение: Unknown inline modifier near index 3
(?itree
   ^
Описание: Unknown inline modifier
Позиция: 3
Неправильный шаблон: (?itree

สร้างแอปพลิเคชันนิพจน์ทั่วไปที่มีประโยชน์โดยใช้ Regex API

นิพจน์ทั่วไปช่วยให้คุณสร้างแอปพลิเคชันการประมวลผลข้อความที่มีประสิทธิภาพได้ ในส่วนนี้ เราจะแสดงแอปพลิเคชันที่มีประโยชน์สองแอปพลิเคชันให้คุณดู ซึ่งหวังว่าจะสนับสนุนให้คุณสำรวจคลาสและวิธีการของ Regex API เพิ่มเติม ภาคผนวกที่สองแนะนำ Lexan: ไลบรารีโค้ดที่นำมาใช้ซ้ำได้สำหรับการวิเคราะห์คำศัพท์ นิพจน์ทั่วไปใน Java ตอนที่ 4 - 3

นิพจน์ทั่วไปและเอกสารประกอบ

เอกสารประกอบเป็นหนึ่งในงานบังคับในการพัฒนาซอฟต์แวร์ระดับมืออาชีพ โชคดีที่นิพจน์ทั่วไปสามารถช่วยคุณในการสร้างเอกสารได้หลายด้าน รหัสในรายการ 1 แยกบรรทัดที่มีความคิดเห็นสไตล์ C บรรทัดเดียวและหลายบรรทัดจากไฟล์ต้นฉบับและเขียนลงในไฟล์อื่น เพื่อให้โค้ดใช้งานได้ ความคิดเห็นจะต้องอยู่ในบรรทัดเดียวกัน รายการ 1. การดึงความคิดเห็น
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class ExtCmnt
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         System.err.println("Способ применения: java ExtCmnt infile outfile");
         return;
      }

      Pattern p;
      try
      {
         // Следующий шаблон определяет многострочные комментарии,
         // располагающиеся в одной строке (например, /* одна строка */)
            // и однострочные комментарии (например, // Howая-то строка).
            // Комментарий может располагаться в любом месте строки.

         p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
      }
      catch (PatternSyntaxException pse)
      {
         System.err.printf("Синтаксическая ошибка в регулярном выражении: %s%n", pse.getMessage());
         System.err.printf("Описание ошибки: %s%n", pse.getDescription());
         System.err.printf("Позиция ошибки: %s%n", pse.getIndex());
         System.err.printf("Ошибочный шаблон: %s%n", pse.getPattern());
         return;
      }

      try (FileReader fr = new FileReader(args[0]);
           BufferedReader br = new BufferedReader(fr);
           FileWriter fw = new FileWriter(args[1]);
           BufferedWriter bw = new BufferedWriter(fw))
      {
         Matcher m = p.matcher("");
         String line;
         while ((line = br.readLine()) != null)
         {
            m.reset(line);
            if (m.matches()) /* Должна соответствовать вся строка */
            {
               bw.write(line);
               bw.newLine();
            }
         }
      }
      catch (IOException ioe)
      {
         System.err.println(ioe.getMessage());
         return;
      }
   }
}
วิธีการmain()ในรายการ 1 จะตรวจสอบไวยากรณ์บรรทัดคำสั่งที่ถูกต้องก่อน จากนั้นจึงรวบรวมนิพจน์ทั่วไปที่ออกแบบมาเพื่อตรวจจับความคิดเห็นบรรทัดเดียวและหลายบรรทัดในอ็อบเจ็กต์Patternคลาส หากไม่มีข้อยกเว้นPatternSyntaxExceptionวิธีการmain()จะเปิดไฟล์ต้นฉบับ สร้างไฟล์เป้าหมาย รับตัวจับคู่เพื่อจับคู่แต่ละบรรทัดที่อ่านกับรูปแบบ จากนั้นอ่านไฟล์ต้นฉบับทีละบรรทัด สำหรับแต่ละบรรทัด จะจับคู่กับรูปแบบความคิดเห็น หากสำเร็จ วิธีการนี้main()จะเขียนสตริง (ตามด้วยการขึ้นบรรทัดใหม่) ไปยังไฟล์เป้าหมาย (เราจะครอบคลุมตรรกะ I/O ของไฟล์ในบทช่วยสอน Java 101 ในอนาคต) คอมไพล์รายการ 1 ดังนี้: javac ExtCmnt.java เรียกใช้แอปพลิเคชันด้วยไฟล์ExtCmnt.javaเป็นอินพุต: java ExtCmnt ExtCmnt.java out คุณควรได้รับผลลัพธ์ต่อไปนี้ในไฟล์ออก:
// Следующий шаблон определяет многострочные комментарии,
 // располагающиеся в одной строке (например, /* одна строка */)
    // и однострочные комментарии (например, // Howая-то строка).
    // Комментарий может располагаться в любом месте строки.
p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
    if (m.matches()) /* Должна соответствовать вся строка */
ในสตริงรูปแบบ อักขระ.*/\\*.*\\*/|.*//.*$เมตาไปป์|ทำหน้าที่เป็นตัวดำเนินการเชิงตรรกะหรือ ซึ่งบ่งชี้ว่าตัวจับคู่ควรใช้ตัวถูกดำเนินการทางซ้ายของโครงสร้างนิพจน์ทั่วไปที่กำหนดเพื่อค้นหารายการที่ตรงกันในข้อความตัวจับคู่ หากไม่มีรายการที่ตรงกัน ตัวจับคู่จะใช้ตัวถูกดำเนินการที่ถูกต้องจากโครงสร้างนิพจน์ทั่วไปที่กำหนดสำหรับการพยายามค้นหาอีกครั้ง (อักขระเมตาวงเล็บในกลุ่มที่บันทึกไว้จะสร้างตัวดำเนินการเชิงตรรกะด้วย) นิพจน์ทั่วไปใน Java ตอนที่ 5
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION