เราขอแจ้งให้คุณทราบถึงการ แปล คำแนะนำสั้นๆ เกี่ยวกับนิพจน์ทั่วไปในภาษา Java ซึ่งเขียนโดย Jeff Friesen สำหรับเว็บไซต์
JavaWorld เพื่อความสะดวกในการอ่าน เราได้แบ่งบทความออกเป็นหลายส่วน
การใช้ 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;
}
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
Metaตัวละคร
โครงสร้างนิพจน์ทั่วไปที่น่าสนใจยิ่งขึ้นจะรวมอักขระตามตัวอักษรเข้ากับอักขระเมตา ตัวอย่างเช่น ในนิพจน์ทั่วไป
a.b
dot 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
และ ลองพิจารณาตัวอย่างต่อไปนี้: ดังที่คุณเห็นจากผลลัพธ์ ในตัวอย่างนี้จะมีเฉพาะอักขระที่ตรงกันใน:
b
c
java RegexDemo [csw] cave
c
cave
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0
คลาสตัวละครกลับหัว
คลาสอักขระกลับหัวจะเริ่มต้นด้วยอักขระเมตา
^
และจับคู่เฉพาะอักขระที่ไม่อยู่ในนั้น ตัวอย่างเช่น คลาส จะจับ คู่
[^abc]
อักขระทั้งหมด
a
ยกเว้น
b
และ
c
พิจารณาตัวอย่างต่อไปนี้:
java RegexDemo "[^csw]" cave
โปรดทราบว่าในระบบปฏิบัติการของฉัน (Windows) ต้องใช้เครื่องหมายคำพูดคู่เนื่องจากเชลล์ถือว่าเครื่องหมายคำพูดเหล่านี้
^
เป็นอักขระหลีก อย่างที่คุณเห็นในตัวอย่างนี้มีเพียงอักขระเท่านั้นและ
a
พบซึ่งมีรายการที่ตรงกันใน:
v
e
cave
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
GO TO FULL VERSION