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

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

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

การใช้ Regular Expression API ในโปรแกรม Java เพื่อจดจำและอธิบายรูปแบบ

ประเภทข้อมูลอักขระและสตริงต่างๆ ของ Java ให้การสนับสนุนในระดับต่ำสำหรับการจับคู่รูปแบบ แต่การใช้เพื่อจุดประสงค์นี้มักจะเพิ่มความซับซ้อนของโค้ดอย่างมาก รับโค้ดที่เรียบง่ายและมีประสิทธิภาพยิ่งขึ้นโดยใช้ Regex API ("Regular Expression API") บทช่วยสอนนี้จะช่วยคุณในการเริ่มต้นใช้งานนิพจน์ทั่วไปและ Regex API ก่อนอื่นเราจะพูดถึงคลาสที่น่าสนใจที่สุดสามคลาสในแพ็คเกจโดยทั่วไปjava.util.regexจากนั้นลองดูภายในคลาสPatternและสำรวจโครงสร้างการจับคู่รูปแบบที่ซับซ้อน ความสนใจ: คุณสามารถดาวน์โหลดซอร์สโค้ด (สร้างโดย Jeff Friesen สำหรับไซต์ JavaWorld) ของแอปพลิเคชันสาธิตได้จากบทความนี้จากที่ นี่

นิพจน์ทั่วไปคืออะไร?

นิพจน์ทั่วไป (นิพจน์ทั่วไป/regex/regexp) คือสตริงที่เป็นรูปแบบที่อธิบายชุดสตริงบางชุด รูปแบบจะกำหนดว่าแถวใดเป็นของชุด รูปแบบประกอบด้วยตัวอักษรและอักขระเมตา—อักขระที่มีความหมายพิเศษมากกว่าความหมายตามตัวอักษร การค้นหารูปแบบคือการค้นหาผ่านข้อความเพื่อค้นหารายการที่ตรงกัน นั่นคือ สตริงที่ตรงกับรูปแบบนิพจน์ทั่วไป Java รองรับการจับคู่รูปแบบผ่าน Regex API API นี้ประกอบด้วยสามคลาส: PatternและMatcherซึ่งPatternSyntaxExceptionอยู่ในแพ็คเกจjava.util.regex:
  • วัตถุคลาสPatternหรือที่เรียกว่าเทมเพลต จะถูกคอมไพล์นิพจน์ทั่วไป
  • วัตถุคลาสMatcherหรือตัวจับคู่เป็นกลไกการตีความรูปแบบสำหรับการค้นหาการจับคู่ในลำดับอักขระ (วัตถุที่คลาสใช้อินเทอร์เฟซjava.lang.CharSequenceและทำหน้าที่เป็นแหล่งข้อความ)
  • อ็อบเจ็กต์คลาสPatternSyntaxExceptionใช้เพื่ออธิบายรูปแบบนิพจน์ทั่วไปที่ไม่ถูกต้อง
Java ยังให้การสนับสนุนการจับคู่รูปแบบผ่านวิธีการต่างๆ ของ java.lang.String. ตัวอย่างเช่น ฟังก์ชันboolean matches (String regex)จะส่งกลับtrueก็ต่อเมื่อสตริงการเรียกตรงกับนิพจน์ทั่วไปทุกregexประการ
วิธีการที่สะดวก
matches()และวิธีการอำนวยความสะดวกที่เน้นนิพจน์ทั่วไปอื่นๆ ของคลาสนั้นStringถูกนำไปใช้ภายใต้ประทุนในลักษณะเดียวกันกับ Regex API

RegexDemo

ฉันสร้างแอปพลิเคชันRegexDemoเพื่อแสดงนิพจน์ทั่วไปของ Java และวิธีการต่างๆ ของPattern, MatcherและPatternSyntaxException. ด้านล่างนี้เป็นซอร์สโค้ดสำหรับแอปพลิเคชันสาธิตนี้ รายการ 1. การสาธิตนิพจน์ทั่วไป
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RegexDemo
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         System.err.println("usage: java RegexDemo regex input");
         return;
      }
      // Преобразуем символьные последовательности начала новой строки (\n) в символы начала строки.
      args[1] = args[1].replaceAll("\\\\n", "\n");
      try
      {
         System.out.println("regex = " + args[0]);
         System.out.println("input = " + args[1]);
         Pattern p = Pattern.compile(args[0]);
         Matcher m = p.matcher(args[1]);
         while (m.find())
            System.out.println("Found [" + m.group() + "] starting at "
                               + m.start() + " and ending at " + (m.end() - 1));
      }
      catch (PatternSyntaxException pse)
      {
         System.err.println("Неправильное регулярное выражение: " + pse.getMessage());
         System.err.println("Описание: " + pse.getDescription());
         System.err.println("Позиция: " + pse.getIndex());
         System.err.println("Неправильный шаблон: " + pse.getPattern());
      }
   }
}
mainสิ่งแรกที่เมธอด คลาส ทำRegexDemoคือตรวจสอบบรรทัดคำสั่ง ต้องใช้สองอาร์กิวเมนต์ ข้อแรกคือนิพจน์ทั่วไป และข้อที่สองคือข้อความอินพุตที่จะใช้ค้นหานิพจน์ทั่วไป คุณอาจจำเป็นต้องใช้อักขระขึ้นบรรทัดใหม่ภายในข้อความที่(\n)ป้อน ซึ่งสามารถทำได้โดยการระบุอักขระ\ตามด้วยอักขระnเท่านั้น ฟังก์ชันmain()แปลงลำดับอักขระนี้เป็นค่า Unicode 10 นิพจน์ทั่วไปใน Java ตอนที่ 1 - 2รหัสส่วนใหญ่RegexDemoอยู่ในไฟล์try-catch. บล็อกtryจะส่งออกนิพจน์ทั่วไปที่กำหนดและข้อความอินพุตก่อน จากนั้นจึงสร้างอ็อบเจ็กต์Patternที่เก็บนิพจน์ทั่วไปที่คอมไพล์แล้ว (นิพจน์ทั่วไปจะถูกคอมไพล์เพื่อปรับปรุงประสิทธิภาพการจับคู่รูปแบบ) ตัวจับคู่จะถูกแยกออกจากวัตถุPatternและใช้เพื่อค้นหารายการที่ตรงกันซ้ำ ๆ จนกว่าจะพบทั้งหมด บล็อกcatchเรียกเมธอดคลาสหลายวิธีPatternSyntaxExceptionเพื่อดึงข้อมูลที่เป็นประโยชน์เกี่ยวกับข้อยกเว้น ข้อมูลนี้จะถูกส่งออกตามลำดับไปยังสตรีมเอาท์พุต ยังไม่จำเป็นต้องทราบรายละเอียดเกี่ยวกับวิธีการทำงานของโค้ด: จะชัดเจนเมื่อเราศึกษา API ในส่วนที่สองของบทความ อย่างไรก็ตาม คุณต้องคอมไพล์รายการ 1 นำโค้ดจากรายการ 1 แล้วพิมพ์คำสั่งต่อไปนี้ที่พร้อมท์คำสั่งเพื่อคอมไพล์RegexDemo: javac RegexDemo.java

คลาส Pattern และโครงสร้าง

คลาสPatternซึ่งเป็นคลาสแรกจากสามคลาสที่ประกอบขึ้นเป็น Regex API เป็นการเป็นตัวแทนที่คอมไพล์ของนิพจน์ทั่วไป เอกสารประกอบคลาส SDK Patternอธิบายโครงสร้างนิพจน์ทั่วไปที่หลากหลาย แต่หากคุณไม่ได้ใช้นิพจน์ทั่วไป บางส่วนของเอกสารประกอบนี้อาจสร้างความสับสน ปริมาณคืออะไร และอะไรคือความแตกต่างระหว่างปริมาณโลภ ไม่เต็มใจ และครอบครอง? คลาสอักขระ ตัวจับคู่ขอบเขต การอ้างอิงด้านหลัง และนิพจน์แฟล็กแบบฝังคืออะไร ฉันจะตอบคำถามเหล่านี้และคำถามอื่นๆ ในหัวข้อต่อไปนี้

สตริงตัวอักษร

โครงสร้างนิพจน์ทั่วไปที่ง่ายที่สุดคือสตริงตามตัวอักษร เพื่อให้การจับคู่รูปแบบสำเร็จ บางส่วนของข้อความที่ป้อนจะต้องตรงกับรูปแบบของโครงสร้างนั้น ลองพิจารณาตัวอย่างต่อไปนี้: java RegexDemo apple applet ในตัวอย่างนี้ เรากำลังพยายามค้นหารูปแบบที่ตรงกันappleในข้อความที่appletป้อน ผลลัพธ์ต่อไปนี้แสดงการจับคู่ที่พบ:
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
เราเห็นนิพจน์ทั่วไปและข้อความอินพุตในเอาต์พุต จากนั้นจึงบ่งชี้ถึงการตรวจจับที่ประสบความสำเร็จappleในแอปเพล็ต นอกจากนี้ ตำแหน่งเริ่มต้นและสิ้นสุดของนัดนี้จะได้รับ: 0และ4ตามลำดับ ตำแหน่งเริ่มต้นระบุตำแหน่งแรกในข้อความที่พบรายการที่ตรงกัน และตำแหน่งสิ้นสุดระบุจุดสุดท้ายของรายการที่ตรงกัน ตอนนี้ สมมติว่าเราให้บรรทัดคำสั่งต่อไปนี้: java RegexDemo apple crabapple คราวนี้เราได้รับผลลัพธ์ดังต่อไปนี้ โดยมีตำแหน่งเริ่มต้นและสิ้นสุดที่แตกต่างกัน:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
มิฉะนั้น ด้วยและappletเป็นนิพจน์ทั่วไปapple- ข้อความที่ป้อน จะไม่พบรายการที่ตรงกัน นิพจน์ทั่วไปทั้งหมดต้องตรงกัน แต่ในกรณี นี้ ข้อความที่ป้อนไม่มีอยู่tหลังappleนิพจน์ทั่วไปใน Java ตอนที่ 1 - 3

Metaตัวละคร

โครงสร้างนิพจน์ทั่วไปที่น่าสนใจยิ่งขึ้นจะรวมอักขระตามตัวอักษรเข้ากับอักขระเมตา ตัวอย่างเช่น ในนิพจน์ทั่วไปa.bdot meta character (.)หมายถึงอักขระใดๆ ที่อยู่ระหว่างaและ b พิจารณาตัวอย่างต่อไปนี้: java RegexDemo .ox "The quick brown fox jumps over the lazy ox." ตัวอย่างนี้ใช้.oxทั้งเป็นนิพจน์ทั่วไปและThe quick brown fox jumps over the lazy ox.เป็นข้อความอินพุต RegexDemoค้นหาข้อความสำหรับการจับคู่ที่เริ่มต้นด้วยอักขระใด ๆ และลงท้ายด้วยox.ผลลัพธ์ของการดำเนินการมีดังนี้:
regex = .ox
input = The quick brown fox jumps over the lazy ox.
Found [fox] starting at 16 and ending at 18
Found [ ox] starting at 39 and ending at 41
ในผลลัพธ์เราจะเห็นรายการที่ตรงกันสองรายการ: foxและox(โดยมีอักขระเว้นวรรคอยู่ด้านหน้า) เมตาอักขระ. จะจับคู่อักขระfในกรณีแรกและช่องว่างในส่วนที่สอง จะเกิดอะไรขึ้นหากคุณแทนที่.oxด้วย metaCharacter .? นั่นคือสิ่งที่เราได้รับจากบรรทัดคำสั่งต่อไปนี้: java RegexDemo . "The quick brown fox jumps over the lazy ox." เนื่องจาก dot metaCharacter ตรงกับอักขระใด ๆRegexDemoจะแสดงผลลัพธ์ที่ตรงกันที่พบสำหรับอักขระทั้งหมด (รวมถึงอักขระจุดต่อท้าย) ของข้อความอินพุต:
regex = .
input = The quick brown fox jumps over the lazy ox.
Found [T] starting at 0 and ending at 0
Found [h] starting at 1 and ending at 1
Found [e] starting at 2 and ending at 2
Found [ ] starting at 3 and ending at 3
Found [q] starting at 4 and ending at 4
Found [u] starting at 5 and ending at 5
Found [i] starting at 6 and ending at 6
Found [c] starting at 7 and ending at 7
Found [k] starting at 8 and ending at 8
Found [ ] starting at 9 and ending at 9
Found [b] starting at 10 and ending at 10
Found [r] starting at 11 and ending at 11
Found [o] starting at 12 and ending at 12
Found [w] starting at 13 and ending at 13
Found [n] starting at 14 and ending at 14
Found [ ] starting at 15 and ending at 15
Found [f] starting at 16 and ending at 16
Found [o] starting at 17 and ending at 17
Found [x] starting at 18 and ending at 18
Found [ ] starting at 19 and ending at 19
Found [j] starting at 20 and ending at 20
Found [u] starting at 21 and ending at 21
Found [m] starting at 22 and ending at 22
Found [p] starting at 23 and ending at 23
Found [s] starting at 24 and ending at 24
Found [ ] starting at 25 and ending at 25
Found [o] starting at 26 and ending at 26
Found [v] starting at 27 and ending at 27
Found [e] starting at 28 and ending at 28
Found [r] starting at 29 and ending at 29
Found [ ] starting at 30 and ending at 30
Found [t] starting at 31 and ending at 31
Found [h] starting at 32 and ending at 32
Found [e] starting at 33 and ending at 33
Found [ ] starting at 34 and ending at 34
Found [l] starting at 35 and ending at 35
Found [a] starting at 36 and ending at 36
Found [z] starting at 37 and ending at 37
Found [y] starting at 38 and ending at 38
Found [ ] starting at 39 and ending at 39
Found [o] starting at 40 and ending at 40
Found [x] starting at 41 and ending at 41
Found [.] starting at 42 and ending at 42
อ้างอิง metaตัวละคร
หากต้องการระบุ.หรือกำหนดอักขระเมตาอื่นใดเป็นอักขระตามตัวอักษรในโครงสร้างนิพจน์ทั่วไป คุณต้องหลีกเลี่ยงอักขระดังกล่าวด้วยวิธีใดวิธีหนึ่งต่อไปนี้:
  • นำหน้าด้วยอักขระแบ็กสแลช
  • วางอักขระเมตานี้ระหว่าง\Qและ\E(เช่น\Q.\E)
อย่าลืมทำซ้ำอักขระใดๆ ที่ปรากฏในสตริงลิเทอรัล เช่นString regex = "\\.";แบ็กสแลช (เช่น\\.หรือ\\Q.\\E) อย่าทำซ้ำแบ็กสแลชที่เป็นส่วนหนึ่งของอาร์กิวเมนต์บรรทัดคำสั่ง

คลาสตัวละคร

บางครั้งคุณต้องจำกัดการจับคู่ที่คุณกำลังมองหาให้เหลือเพียงชุดอักขระเฉพาะ ตัวอย่างเช่น ค้นหาข้อความเพื่อหาสระa, e, i, oและuโดยแต่ละตัวอักษรสระจะถือว่าตรงกัน ในการแก้ปัญหาดังกล่าว เราจะได้รับความช่วยเหลือจากคลาสอักขระที่กำหนดชุดอักขระระหว่างอักขระเมตาของวงเล็บเหลี่ยม ( [ ]) คลาสนี้Patternรองรับคลาสอักขระอย่างง่าย คลาสช่วง คลาสผกผัน สหภาพ อินเตอร์เซกชัน และคลาสการลบ เราจะดูทั้งหมดตอนนี้

คลาสตัวละครอย่างง่าย

คลาสอักขระแบบง่ายประกอบด้วยอักขระที่วางเคียงข้างกันและจับคู่เฉพาะอักขระเหล่านั้นเท่านั้น ตัวอย่างเช่น คลาสจะ จับ คู่[abc]อักขระaและ ลองพิจารณาตัวอย่างต่อไปนี้: ดังที่คุณเห็นจากผลลัพธ์ ในตัวอย่างนี้จะมีเฉพาะอักขระที่ตรงกันใน: bcjava RegexDemo [csw] caveccave
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0

คลาสตัวละครกลับหัว

คลาสอักขระกลับหัวจะเริ่มต้นด้วยอักขระเมตา^และจับคู่เฉพาะอักขระที่ไม่อยู่ในนั้น ตัวอย่างเช่น คลาส จะจับ คู่[^abc]อักขระทั้งหมดaยกเว้นbและ cพิจารณาตัวอย่างต่อไปนี้: java RegexDemo "[^csw]" cave โปรดทราบว่าในระบบปฏิบัติการของฉัน (Windows) ต้องใช้เครื่องหมายคำพูดคู่เนื่องจากเชลล์ถือว่าเครื่องหมายคำพูดเหล่านี้^เป็นอักขระหลีก อย่างที่คุณเห็นในตัวอย่างนี้มีเพียงอักขระเท่านั้นและaพบซึ่งมีรายการที่ตรงกันใน: vecave
regex = [^csw]
input = cave
Found [a] starting at 1 and ending at 1
Found [v] starting at 2 and ending at 2
Found [e] starting at 3 and ending at 3

คลาสตัวละครช่วง

คลาสอักขระช่วงประกอบด้วยอักขระสองตัวคั่นด้วยยัติภังค์ ( -) อักขระทั้งหมด เริ่มต้นด้วยอักขระทางด้านซ้ายของยัติภังค์และลงท้ายด้วยอักขระทางด้านขวา เป็นส่วนหนึ่งของช่วง ตัวอย่างเช่น ช่วง[a-z]จะตรงกับตัวอักษรละตินตัวพิมพ์เล็กทั้งหมด นี่เทียบเท่ากับการกำหนดคลาสแบบ[abcdefghijklmnopqrstuvwxyz]ง่าย ลองพิจารณาตัวอย่างต่อไปนี้: java RegexDemo [a-c] clown ตัวอย่างนี้จะจับคู่เฉพาะอักขระcที่ตรงกันในclown:
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
นิพจน์ทั่วไปใน Java ส่วนที่ 2 นิพจน์ทั่วไปใน Java ส่วนที่ 3 นิพจน์ทั่วไปใน Java ส่วนที่ 4 นิพจน์ทั่วไปใน Java ส่วนที่ 5
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION