1. regex (นิพจน์ทั่วไป): RegularExpressions (แทนที่ StringTokenizer) เครื่องมืออันทรงพลังสำหรับการประมวลผลสตริง ซึ่งเป็นที่นิยมใน Unix นั้น Perl ดียิ่งขึ้นเมื่อใช้ regex
ส่วนใหญ่ใช้ในการจับคู่สตริง การค้นหา และการแทนที่ ตัวอย่างเช่น: การจับคู่ IP (ช่วงน้อยกว่า 256) ใช้งานง่ายด้วยนิพจน์ทั่วไป แยกที่อยู่อีเมลจำนวนมากจากหน้าเว็บเพื่อส่งสแปม ประกอบด้วย Matcher (ผลลัพธ์ของการจับคู่สตริงกับรูปแบบ) และรูปแบบ
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* บอกว่าสตริงนี้ตรงกับนิพจน์ทั่วไปที่กำหนดหรือไม่ (รวมถึงสตริงด้วย)
-
System.out.println("abc".matches("..."));//Each "." แสดงถึงอักขระ
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* แทนที่ตัวเลขทั้งหมดในสตริงด้วย "-" วิธีการทั่วไปต้องใช้การตัดสินตัวอักษรทีละตัว
* "//d" แทนตัวเลขใดๆ หรือแทนที่ด้วย "[0-9]";
* "//D" หมายถึงตัวเลขที่ไม่ใช่หลักหรือแทนที่ด้วย "[^0-9]"
-
System.out.println("ab54564654sbg48746bshj".replaceAll("[0-9]", "-"));// แต่ละตัว "." แสดงถึงอักขระหนึ่งตัว
สอง,
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* คอมไพล์ คอมไพล์นิพจน์ทั่วไปที่กำหนดเป็นรูปแบบ (การคอมไพล์แต่ละครั้งต้องใช้เวลา) {3} หมายถึงสามครั้งพอดี
* X{n} X n ครั้งพอดี
* X{n,} X อย่างน้อย n ครั้ง
* X{n,m} X อย่างน้อย n ครั้ง แต่ไม่เกิน m ครั้ง
-
รูปแบบ p = Pattern.compile("[az]{3}");
Matcher m = p.matcher("ggs");//สร้างตัวจับคู่ที่ตรงกับอินพุตที่กำหนดด้วยรูปแบบนี้ ภายในมีการสร้างออโตเมติกสถานะลำดับความสำคัญขึ้นจริง (หลักการรวบรวม)
//สตริงที่จะจับคู่ใน matcher และmatch จริงๆ แล้วคือ CharSequence (อินเทอร์เฟซ) แต่ String ใช้อินเทอร์เฟซนี้และมีความหลากหลาย
System.out.println(m.matches());//หากเป็น "ggss" จะไม่ตรงกัน
//คุณสามารถ "ggs".matches("[az]{3}") ได้โดยตรงเสมอ แต่สิ่งที่กล่าวมาข้างต้นมีข้อดี อย่างน้อยก็มีประสิทธิภาพมากกว่า และ Pattern และ Matcher มีฟังก์ชันมากมาย
3. เรียก Meta Character ใน regex ". * +"; ctrl + shift + "/" หมายถึงความคิดเห็น แทนที่ด้วย "/" เพื่อลบความคิดเห็น
คัดลอกรหัสรหัส ดังต่อไปนี้:
"a".matches(".");//true, "." แสดงถึงอักขระใดๆ รวมถึงอักขระจีนด้วย
"aa".matches("aa");//true กล่าวคือ สตริงธรรมดาก็สามารถใช้เป็นนิพจน์ทั่วไปได้เช่นกัน
-
* จริง "*" หมายถึง 0 อักขระขึ้นไป แต่อักขระต่อไปนี้จะต้องเหมือนกับอักขระตัวแรก
* มิฉะนั้นจะเป็นเท็จ กล่าวคือ จะถูกตัดสินว่าสตริงเป็นสตริงที่ประกอบด้วยอักขระตัวเดียวหรือไม่
-
"aaaa".matches("a*");
"".matches("a*");//true
"aaa".matches("a?");//true หนึ่งครั้งหรือ 0 ครั้ง
"".matches("a?");//true
"a".matches("a?");//true
"544848154564113".matches("//d{3,100}");//true
//นี่เป็นการตัดสิน IP ที่ง่ายที่สุด แต่ถ้าเกิน 255 ก็ไม่สามารถตัดสินได้
"192.168.0.aaa".matches("//d{1,3}//.//d{1,3}//.//d{1,3}//d{1,3}" );
"192".ตรงกัน("[0-2][0-9][0-9]");
4. [abc] หมายถึงการจับคู่อักขระใดๆ [^abc] หมายถึงอักขระอื่นที่ไม่ใช่ abc (จะต้องยังคงเป็นตัวอักษร และจะส่งคืนค่า false หากเป็นสตริงว่าง) "[az ]|[AZ]" เป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก [AZ&&[ABS]] หมายถึงตัวอักษรตัวพิมพ์ใหญ่และ ABS ตัวใดตัวหนึ่ง
คัดลอกรหัสรหัส ดังต่อไปนี้:
//ฉันพบว่าไม่มีความแตกต่างระหว่าง |. และ || แต่มีความแตกต่างระหว่าง & และ && ฉันไม่รู้ว่านี่เป็นวิธีที่ถูกต้องหรือไม่
System.out.println("C".matches("[AZ&&[ABS]]"));//false
System.out.println("C".matches("[AZ&[ABS]]"));//true
System.out.println("A".matches("[AZ&&[ABS]]"));//true
System.out.println("A".matches("[AZ&[ABS]]"));//true
System.out.println("C".matches("[AZ|[ABS]]"));//true
System.out.println("C".matches("[AZ||[ABS]]"));//true
5. /w อักขระคำ: [a-zA-Z_0-9] เมื่อจับคู่ชื่อผู้ใช้ /s อักขระว่าง: [ /t/n/x0B/f/r]; /S อักขระที่ไม่ว่างเปล่า: [^/s ] ;/W อักขระที่ไม่ใช่คำ: [^/w]
คัดลอกรหัสรหัส ดังต่อไปนี้:
" /n/t/r".matches("//s{4}");//true
" ".matches("//S");//false
"a_8".matches("//w{3}");//true
//"+" หมายถึง ครั้งเดียวหรือหลายครั้ง
"abc888&^%".matches("[az]{1,3}//d+[&^#%]+");//true
-
* อักขระที่จะจับคู่เป็นเพียงแบ็กสแลช แต่ไม่สามารถเขียนเป็น "/" แล้วรวมกับ ",
* ก่อนหน้า "ไม่สามารถจับคู่ได้จะส่งผลให้ CE
* ไม่สามารถตามด้วย "//" ไม่เช่นนั้นจะเกิดข้อผิดพลาดรันไทม์ (ไม่มีปัญหาในการคอมไพล์) ต้องเขียนเป็น "////"
-
System.out.println("//".matches("////"));//true
6. คลาสอักขระ POSIX (US-ASCII เท่านั้น)
คัดลอกรหัสรหัส ดังต่อไปนี้:
/p{Lower} อักขระตัวอักษรตัวพิมพ์เล็ก: [az] ;/p{Upper} อักขระตัวอักษรตัวพิมพ์ใหญ่: [AZ] ;/p{ASCII} ASCII ทั้งหมด: [/x00-/x7F] ;/p{Alpha} อักขระตัวอักษร: [/p{Lower}/p{Upper}] ;/p{Digit} เลขฐานสิบ: [0-9]
7. ตัวจับคู่ขอบเขต
↑ จุดเริ่มต้นของบรรทัด $ สิ้นสุดบรรทัด/b ขอบเขตของคำ/B ขอบเขตที่ไม่ใช่คำ/A จุดเริ่มต้นของอินพุต/G สิ้นสุดการจับคู่ก่อนหน้า/Z สิ้นสุดอินพุต, ใช้สำหรับตัวยุติสุดท้ายเท่านั้น (ถ้ามี)
/z สิ้นสุดอินพุต
คัดลอกรหัสรหัส ดังต่อไปนี้:
"hello world".matches("^h.*");//จุดเริ่มต้นของบรรทัด ^
"hello world".matches(".*ld$");//สิ้นสุด $line
"hello world".matches("^h[az]{1,3}o//b.*");///bword ขอบเขต
"helloworld".matches("^h[az]{1,3}o//b.*");
" /n".matches("^[//s&&[^//n]]*//n$");//ตัดสินบรรทัดว่าง ซึ่งขึ้นต้นด้วยอักขระว่าง
8. คุณยังสามารถใช้ m.start() และ m.end() ภายใต้เมธอด find เพื่อส่งคืนตำแหน่งถัดไประหว่างตำแหน่งเริ่มต้นและตำแหน่งสิ้นสุด หากไม่พบ จะเกิดข้อผิดพลาดขึ้น
คัดลอกรหัสรหัส ดังต่อไปนี้:
รูปแบบ p = Pattern.compile("//d{3,5}");
สตริง s = "133-34444-333-00";
Matcher m = p.matcher(s);
m.matches();//matches ตรงกับสตริงทั้งหมด
ม.รีเซ็ต();
-
* หากเรียกวิธีการรีเซ็ตเป็นอันดับแรกด้านล่าง เอาต์พุต true, true, true, false
* มิฉะนั้น การค้นหาสุดท้ายจะแสดงผลเป็นเท็จด้วย
*เหตุผลมีดังนี้:
* การจับคู่ตรงกับ "-" ตัวแรกและพบว่าไม่ตรงกัน แต่ทั้ง 4 ตัวถูกกินเข้าไป การจับคู่อีกครั้งจะเริ่มจาก
* 34444 เริ่มต้น และการค้นหาครั้งที่สองเริ่มต้นจาก 333 เนื่องจากการค้นหาตรงกับลำดับถัดไป
* วิธีการรีเซ็ตช่วยให้ไม้ขีดไฟคายสายที่ไม้ขีดกินออกมา
* โดยสรุป: ต้องใช้การรีเซ็ตระหว่างการจับคู่และการค้นหาเนื่องจากจะส่งผลซึ่งกันและกัน
-
-
ม.ค้นหา();
ม.ค้นหา();
m.find();//พยายามค้นหาลำดับถัดไปของลำดับอินพุตที่ตรงกับรูปแบบนี้
ม.ค้นหา();
-
* พยายามจับคู่ลำดับอินพุตโดยเริ่มต้นที่จุดเริ่มต้นของขอบเขตด้วยรูปแบบนี้
* ผู้เขียน Thinking in java วิพากษ์วิจารณ์วิธีนี้อย่างรุนแรง เนื่องจากยังไม่ชัดเจนจากคำที่จะเริ่มจับคู่
* ข้อมูลต่อไปนี้เป็นจริง เนื่องจากเริ่มต้นใหม่ทุกครั้ง
-
m.มองที่();
m.มองที่();
m.มองที่();
m.มองที่();
9. การเปลี่ยนสายอักขระ
คัดลอกรหัสรหัส ดังต่อไปนี้:
นำเข้า java.util.regex.Matcher;
นำเข้า java.util.regex.Pattern;
TestRegexReplacement ระดับสาธารณะ {
โมฆะสาธารณะคงหลัก (สตริง [] args) {
Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//พารามิเตอร์ต่อไปนี้เป็นจำนวนเต็ม ซึ่งหมายถึง "ไม่คำนึงถึงขนาดตัวพิมพ์"
Matcher m = p.matcher("Java java hxsyl Ilovejava java JaVaAcmer");
ในขณะที่ (m.find ()) {
System.out.println(m.group());//m.group จะส่งออก java ทั้งหมด (ไม่สนใจตัวพิมพ์)
-
String s = m.replaceAll("Java");//String ก็มีเมธอดนี้เช่นกัน
System.out.println(s);
m.reset();//ต้องเพิ่มเนื่องจาก find และ matcher มีผลกระทบต่อกัน
StringBuffer sb = StringBuffer ใหม่ ();
อินท์ i = 0;
-
* วิธีการต่อไปนี้คือการแทนที่เลขคี่ของ java ที่พบด้วย "Java" และแทนที่เลขคู่ด้วย "java"
-
ในขณะที่ (m.find ()) {
ฉัน++;
//ไม่สามารถเขียนเป็น i&1 ได้โดยตรง และต้องแปลงเป็นบูลีน
ถ้า((i&1)==1) {
m.appendReplacement(sb, "Java");
}อื่น {
m.appendReplacement(sb, "java");
-
-
m.appendTail(sb);//เพิ่มสตริงที่เหลือหลังจากพบ java ล่าสุด
System.out.println(sb);//หากไม่มีการรีเซ็ต จะมีเอาต์พุตเฉพาะ Acmer เท่านั้น
-
-
10. การจัดกลุ่ม
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* เพิ่มวงเล็บตามลำดับ ไม่นับวงเล็บปีกกาด้านนอกสุด โดยวงเล็บซ้ายตัวแรกคือกลุ่มแรก
-
รูปแบบ p = Pattern.compile("(//d{3,5})([az]{2})");
สตริง s = "123aaa-77878bb-646dd-00";
Matcher m = p.matcher(s);
ในขณะที่ (m.find ()) {
System.out.println(m.group());
System.out.println(m.group(1));//ส่งออกหมายเลขที่ตรงกันแต่ละคู่
System.out.println(m.group(2));//ส่งออกตัวอักษรที่ตรงกันแต่ละคู่
-
11. บันทึกอีเมลจากหน้าเว็บ
คัดลอกรหัสรหัส ดังต่อไปนี้:
นำเข้า java.io.BufferedReader;
นำเข้า java.io.FileNotFoundException;
นำเข้า java.io.FileReader;
นำเข้า java.io.IOException;
นำเข้า java.util.regex.Matcher;
นำเข้า java.util.regex.Pattern;
-
* หากต้องการวิธีการเลี้ยงใดๆ กรุณาระบุชื่อวิธีการเลี้ยงก่อน
* จากนั้น ctrl + 1 จะแสดงรายการคำแนะนำ และระบบจะสร้างวิธีนี้ขึ้นมา
-
EmailSpider ระดับสาธารณะ {
โมฆะสาธารณะคงหลัก (สตริง [] args) {
// TODO ต้นขั้ววิธีการสร้างอัตโนมัติ
พยายาม {
BufferedReader br = BufferedReader ใหม่ (FileReader ใหม่ ("F://regex.html"));
สายอักขระ = "";
พยายาม {
ในขณะที่ ((line=br.readLine())!=null) {
แก้ (เส้น);
-
} จับ (IOException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
} จับ (FileNotFoundException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
โมฆะคงที่ส่วนตัวแก้ (สายสตริง) {
// TODO ต้นขั้ววิธีการสร้างอัตโนมัติ
//หากนิพจน์ทั่วไปไม่ตรงกับฟังก์ชันที่เกี่ยวข้อง ก็จะไม่ทำให้เกิดข้อผิดพลาดเนื่องจากเป็นสตริง
รูปแบบ p = Pattern.compile("[//w[.-]]+@[//w[.-]]+//.[//w]+");
Matcher m = p.matcher(เส้น);
ในขณะที่ (m.find ()) {
System.out.println(m.group());
-
-
-
12. สถิติรหัส
คัดลอกรหัสรหัส ดังต่อไปนี้:
ดูรหัส
-
* นับจำนวนบรรทัดว่าง บรรทัดแสดงความคิดเห็น และบรรทัดโปรแกรมในโค้ด
* จริงๆ แล้ว คุณสามารถใช้ startWith และendsWith ใน String ได้ด้วย
* หากผู้จัดการโครงการใช้ จะต้องนับด้วยว่าจำนวนอักขระในแต่ละบรรทัดลงท้ายด้วย {; เพื่อป้องกันความเกียจคร้าน
-
นำเข้า java.io.BufferedReader;
นำเข้า java.io.File;
นำเข้า java.io.FileNotFoundException;
นำเข้า java.io.FileReader;
นำเข้า java.io.IOException;
CoderCount ระดับสาธารณะ {
เส้นปกติแบบยาวคงที่ = 0;
commentLines แบบยาวคงที่ = 0;
whiteLines ยาวคงที่ = 0;
โมฆะสาธารณะคงหลัก (สตริง [] args) {
ไฟล์ f = ไฟล์ใหม่ ("D://share//src");
ไฟล์[] codeFiles = f.listFiles();
สำหรับ (ไฟล์ลูก: codeFiles){
if(child.getName().matches(".*//.java$")) {
แก้(ลูก);
-
-
System.out.println("normalLines:" + NormalLines);
System.out.println("commentLines:" + commentLines);
System.out.println("whiteLines:" + whiteLines);
-
การแก้ไขโมฆะคงที่ส่วนตัว (ไฟล์ f) {
BufferedReader br = null;
ความคิดเห็นบูลีน = เท็จ;
พยายาม {
br = ใหม่ BufferedReader (FileReader ใหม่ (f));
สายอักขระ = "";
ในขณะที่ ((line = br.readLine()) != null) {
-
* //บางบรรทัดแสดงความคิดเห็นมีแท็บอยู่ข้างหน้า
* ไม่สามารถเขียนหลัง readLine ได้
* บรรทัดสุดท้ายจะเป็นตัวชี้ว่าง
-
เส้น = line.trim();
//readLine ลบการขึ้นบรรทัดใหม่หลังจากอ่านสตริงแล้ว
ถ้า(line.matches("^[//s&&[^//n]]*$")) {
เส้นสีขาว++;
} อื่น ๆ ถ้า (line.startsWith("/*") && !line.endsWith("*/")) {
commentLines++;
ความคิดเห็น = จริง;
} อื่น ๆ ถ้า (line.startsWith("/*") && line.endsWith("*/")) {
commentLines++;
} อื่นถ้า (จริง == ความคิดเห็น) {
commentLines++;
ถ้า(line.endsWith("*/")) {
ความคิดเห็น = เท็จ;
-
} อื่นถ้า (line.startsWith("//")) {
commentLines++;
} อื่น {
เส้นปกติ++;
-
-
} จับ (FileNotFoundException จ) {
e.printStackTrace();
} จับ (IOException จ) {
e.printStackTrace();
} ในที่สุด {
ถ้า(br != null) {
พยายาม {
br.ปิด();
br = โมฆะ;
} จับ (IOException จ) {
e.printStackTrace();
-
-
-
-
-
13. ปริมาณ
รวม? *+; ค่าเริ่มต้นคือ Greedy เช่นเดียวกับ Reluctant และ Possessive (พิเศษ)
คัดลอกรหัสรหัส ดังต่อไปนี้:
//เพิ่มการจัดกลุ่มให้ดูชัดเจนยิ่งขึ้น
รูปแบบ p = Pattern.compile("(.{3,10})+[0-9]");
String s = "aaaa5bbbb6";//ความยาวคือ 10
Matcher m = p.matcher(s);
-
* ตอนนี้เอาต์พุต 0-10 ค่าเริ่มต้นคือ Greedy กลืนอักขระ 10 ตัวก่อน ค้นหาว่าไม่ตรงกัน คายออกมาหนึ่งตัวแล้วพบว่าตรงกัน
* ถ้า Pattern.compile("(.{3,10}?)+[0-9]") กลายเป็น Reluctant มันจะกลืนอักขระสามตัวก่อน ค้นหาอักขระที่ไม่ตรงกัน แล้วกลืนต่อไปจนกว่าจะตรงกัน และเอาต์พุตเป็น 0 ถึง 5;
* หาก Pattern.compile("(.{3,10}++)+[0-9]") เป็น Possessive (เฉพาะ) มันจะกลืนอักขระ 10 ตัวก่อนด้วย แต่ไม่คายอักขระออกมา จากนั้นจะไม่ตรงกัน ,
* วิธีนี้ส่วนใหญ่จะใช้เมื่อต้องการประสิทธิภาพสูง (อาจมีข้อผิดพลาด)
-
ถ้า(m.find()) {
System.out.println(m.start() + "----" + m.end());
}อื่น {
System.put.println("ไม่ตรงกัน!");
-
14. อาหารเสริม (กลุ่มไม่จับ)
คัดลอกรหัสรหัส ดังต่อไปนี้:
//ความหมายของกลุ่มที่ไม่จับภาพนั้นตรงกันข้ามกับความหมายที่แท้จริงซึ่งหมายถึงการจับหากตรงกัน
รูปแบบ p = Pattern.compile("(?=a).{3}");
-
* เอาต์พุต a66 ซึ่งเทียบเท่ากับกำหนดให้เริ่มต้นด้วย a คุณยังสามารถเขียน Pattern.compile("[a].{2}");
* หาก Pattern.compile(".{3}(?!=a)") ไม่ได้ลงท้ายด้วย {2}[^a] แต่อักขระถัดไปไม่ใช่ (lookahead) 44a, 66b จะถูกส่งออก ดังนั้นสิ่งนี้จึงไม่ได้ใช้กันทั่วไป
* ถ้าเป็น Pattern.compile(".{3}(?=a)") ก็จะได้เอาท์พุต 444 (เพราะ ?=a เป็น lookahead) หากวางไว้ด้านหน้า จะรวมอยู่ในกลุ่ม และหากวางไว้ด้านหลังจะไม่รวมอยู่ในกลุ่ม
-
-
-
สตริง s = "444a66b";
Matcher m = p.matcher(s);
ในขณะที่ (m.find ()) {
System.out.println(m.group());
-
15. การอ้างอิงด้านหลัง
คัดลอกรหัสรหัส ดังต่อไปนี้:
รูปแบบ p = Pattern.compile("(//d//d)//1");
-
* เอาต์พุตเป็นจริง //1 หมายถึงเหมือนกับกลุ่มแรก หากเปลี่ยนเป็น 1213 จะผิด
* ถ้าเป็น Pattern.compile("(//d(//d))//2") จะต้องเปลี่ยนเป็น 122
-
-
สตริง s = "1212";
Matcher m = p.matcher(s);
System.out.println(m.matches());
16. คำย่อของธง
"." ไม่ตรงกับการขึ้นบรรทัดใหม่ เพียงจำไว้ว่า CASE_INSENSITIVE ตัวย่อของ "การจับคู่ที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่สามารถเปิดใช้งานผ่านนิพจน์แฟล็กแบบฝัง (?i)"