正则表达式初级入门【原】
java正则表达式 pattern基本语法
其它参考: oracle正则表达式
import java.util.regex.*;
1 import java.util.regex.*; 2 3 Pattern p = Pattern.compile("[a-z]{3}"); //编译后要匹配的模式 4 Matcher m =p.matcher("abc"); 5 soup(m.matches());// matches匹配整个字符串 6 soup("abc".matches("[a-z]{3}");//该种方式没有编译,处理时会较慢 7 8 ?0->1个字符 . 1个字符 * 0->多个字符 + 1->多个字符 9 soup("".matches("a?") && "".matches("a*")); //true,0宽度匹配. 10 "^[abc]"=>以abc其中之一开头 (开头) 11 "[^abc]"=>取除了abc三个字符之外的字符 (取反) 12 \\w 等于 "[a-zA-Z_0-9]" 13 \\d 等于[0-9] \D 等于 [^0-9] 14 "\\".matches("\\\\"); //true 15 \\代表一个\ 前面两个\\成为一个\ , 后面两个\\也成为一个\,然后因为在字符串中\\两个再转义成\ 16 \\s 等于[\t\n\r\f] 17 soup(" \n".matches("^[\\s&&[^\\n]]*\\n$"); {开头是除\n外的空格字符 结尾是\n} $表示结尾 ,用来检测该行是不是空白行 18 \\b 单词边界 如abc def-ghi (cd之间 fg之间就是\b) 19 soup("Hello sir".matches("^H[a-z]o\\b.*")//true 20 soup("Hellosir".matches("^H[a-z]o\\b.*")//false
21 "a|bc|def" //包含a或包含bc或包含def
另附javascript js 正则表达式样例 : js正则表达式【原】==>https://www.cnblogs.com/whatlonelytear/p/6305950.html 总体正则语法相近,但不完全相同,仅作入口,不值得参考.
我的正则使用日记
package com.bobo.code.web.controller; import java.util.regex.*; public class Pattern_Test { public static void main(String[] args) { //patternOr(); //pattern1(); //pattern2(); //pattern3(); //pattern4(); //高级用法 //patternGreedyData(); //patternLazyData(); //超级用法 //patternWithGroupCount2(); //patternFilterGroupCount1(); } public static void patternOr() { Pattern p = Pattern.compile("小区|幢|楼 "); Matcher m = p.matcher("abc123小区456def"); System.out.println(m.find()); } public static void pattern1() { Pattern p = Pattern.compile("\\d{3,5}"); Matcher m = p.matcher("012A45678B9"); System.out.println(m.matches()); m.reset(); while (m.find()) { System.out.println("" + m.start() + "->" + (m.end() - 1)); } } public static void pattern2() { Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE); String str = "jaVa_JaVa_JAVa_jAVA_abc"; Matcher m = p.matcher(str); StringBuffer sb = new StringBuffer(); int number = 0; while (m.find()) { number++; if (number % 2 == 0) { //偶号全改成java m.appendReplacement(sb, "java"); } else { //奇号全改成JAVA m.appendReplacement(sb, "JAVA"); }// 将该次匹配的替换成指定字符串"JAVA"后, // 再将上一次匹配的m.end()到这一次匹配的m.end()-1的这一段字符添加到sb中 } m.appendTail(sb); //将最后一次匹配的m.end()到末尾全添加到sb中 System.out.println(sb); //m.reset(); //System.out.println( m.replaceAll("JAVA") );//全替换成 JAVA } public static void pattern3() { Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})"); Matcher m = p.matcher("123aa-34567bb-189cc-00"); while (m.find()) { System.out.println(m.group(0)); } m.reset(); System.out.println("_____________________"); while (m.find()) { System.out.println(m.group(1)); } m.reset(); System.out.println("_____________________"); while (m.find()) { System.out.println(m.group(2)); } } public static void pattern4() { Pattern p1 = Pattern.compile(".{3,10}[0-9]");//Greedy //默认贪婪的: 先直接取10个,aaaa5bbbb7| 不匹配,吐一个aaaa5bbbb|7匹配了,于是0 start->10 end Pattern p2 = Pattern.compile(".{3,10}?[0-9]");//Reluctant //不情愿,勉强的: 先取aaa 3个,不匹配,吃一个aaaa 4个还不匹配,再吃一个aaaa5 Pattern p3 = Pattern.compile(".{3,10}+[0-9]");//Possessive //独占的: 直接全取aaaa5bbbb6不吐出来,故not match //0123456789 String s = "aaaa5bbbb7"; Matcher m = p2.matcher(s); if (m.find()) { System.out.println(m.start() + "--->" + m.end()); } } //贪婪模式(默认模式) //true //2 //0组 --》 abcdcd //1组 --》 abcdcd //2组 --》 public static void patternGreedyData() { Pattern p = Pattern.compile("(.+)(.*)"); Matcher m = p.matcher("abcdcd"); System.out.println(m.find()); System.out.println(m.groupCount()); for (int i = 0; i < m.groupCount();i++) { System.out.println(i + "组 --》 " + m.group(i)); } System.out.println(m.groupCount() + "组 --》 " + m.group(m.groupCount())); } //懒猫模式(.*?) 等 (.+?) //true //2 //0组 --》 abcdcd //1组 --》 a //2组 --》 bcdcd public static void patternLazyData() { Pattern p = Pattern.compile("(.+?)(.*)"); Matcher m = p.matcher("abcdcd"); System.out.println(m.find()); System.out.println(m.groupCount()); for (int i = 0; i < m.groupCount();i++) { System.out.println(i + "组 --》 " + m.group(i)); } System.out.println(m.groupCount() + "组 --》 " + m.group(m.groupCount())); } //匹配组 //true //2 //0组 --》 aabb //1组 --》 aa //2组 --》 bb public static void patternWithGroupCount2() { Pattern p = Pattern.compile("(aa)(bb)"); Matcher m = p.matcher("aabb"); System.out.println(m.find()); System.out.println(m.groupCount()); for (int i = 0; i < m.groupCount();i++) { System.out.println(i + "组 --》 " + m.group(i)); } System.out.println(m.groupCount() + "组 --》 " + m.group(m.groupCount())); } //过滤组 //true //1 //0组 --》 aabb //1组 --》 bb public static void patternFilterGroupCount1() { Pattern p = Pattern.compile("(?:aa)(bb)");//aa这一组不会进入group,如果后续不取aa,则为了提升性能,可能添加?:进行组过滤 Matcher m = p.matcher("aabb"); System.out.println(m.find()); System.out.println(m.groupCount()); for (int i = 0; i < m.groupCount();i++) { System.out.println(i + "组 --》 " + m.group(i)); } System.out.println(m.groupCount() + "组 --》 " + m.group(m.groupCount())); } }
正则解析工具
package king;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* http post发送工具
* @author King
*
*/
public class PatternTool {
/**
* 从regex表达式中提供对应的值,默认取group 1<br/>
* 举例: abc(*.)xyz即取从左往右第一个括号中匹配的内容<br/>
* @author King
*/
public static String parsePattern(String regex, String content) {
return parsePattern(regex,content,1);
}
/**
* 从regex表达式中提供对应的值
* @author King
*/
public static String parsePattern(String regex, String content ,int groupNum) {
String ret = "";
String str = "";
String output ="";
try {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
if (m.find()) {
for(int i = 0 ; i <= m.groupCount() ; i ++){
if(i == 0){
}else{
str = m.group(i);
output = String.format("解析得正则表达式%s中group(%d)匹配的值\n",regex,i);
System.out.println(output);
System.out.println(str);
}
}
ret = m.group(groupNum);
System.out.println("返回第"+groupNum+"组匹配到的内容:\n"+ret);
}else{
System.out.println("未解析到正则表达式"+regex+"匹配的的值\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
public static void main(String[] args) {
String content = "xxx<name>king</name>yyyy";
//希望匹配<CONTENT>.*<![CDATA[.*]]>.*</CONTENT>
String regex = "<name>(.*)</name>";
String ret = parsePattern(regex,content,1);
}
}
正则表达式匹配带换行符的情况
可使用 [\s\S]* [\d\D]* [\w\W]* 等去匹配.哈哈
import java.util.regex.Matcher; import java.util.regex.Pattern; public class Pattern_R_N { public static void main(String[] args) { //$$$$$匹配包括换行符在内的任意字符 String arg = "<BODY>\r\n123abc\r\n456\r\ndef</BODY>"; String regex1 = "<BODY>([\\s\\S]*)</BODY>" ;//重点,尽量用这种 Pattern p1 = Pattern.compile( regex1 ); Matcher m1 =p1.matcher(arg); if(m1.find()){ System.out.println(m1.group(1)); }else{ System.out.println(regex1+"未匹配到"+arg); } System.out.println("____________________________________"); String regex2 = "<BODY>(.*)*</BODY>" ; Pattern p2 = Pattern.compile( regex2); Matcher m2 =p2.matcher(arg); if(m2.find()){ System.out.println(m2.group(1)); }else{ System.out.println(regex2+"未匹配到"+arg); } } }
正则表达式替换 > < 中的空格
main方法,这个正则"(?<=>)\\s+(?=<)"到目前为止本人仍无法理解
public static void main(String[] args) { String content = "<A>1</A> <B> 2</B> <C> 3 </C>"; content = content.replaceAll("(?<=>)\\s+(?=<)", ""); System.out.println(content); }
结果
<A>1</A><B> 2</B><C> 3 </C>
正式表表达式替换所有特殊字符成空格
main方法
public static void main(String[] args) throws Exception { Pattern pattern = Pattern.compile("[`~!@#$%^&*()+=|{}':;]"); String content = "a`b~c!d@e#f$g%h^i&j*k(l)m+n=o|p{q}r's:t;u"; Matcher matcher = pattern.matcher(content); String result= matcher.replaceAll(" ").trim(); System.out.println(result); }
结果:
a b c d e f g h i j k l m n o p q r s t u
正则表达式(从oracle提取时的)奇葩问题 :
假如我们要把正则表达式放到oracle数据库里,想用的时候再提取出来,那么问题来了....
前题:你已经把标准的java正则表达式放在oracle中如下(非打印语句,而是调试时内容)
requestHead\"\\s*:.*userId\"\\s*:\\s*\"(.+?)\"
然而当我们用java程序从oracle中select提取出来的时候,却变成如下:(非打印语句,而是调试时内容)
requestHead\\"\\\\s*:.*userId\\"\\\\s*:\\\\s*\\"(.+?)\\"
应该是被转义了.
所以我们为了能正确使用,我们需要做如下替换:
format = format.replace("\\\\", "\\");
以上语句中第一个参数"\\\\"是pattern表达式,所以\\代表\, 于是\\\\代表\\ ,
而上语句中第二个参数"\\"是普通String,所以\\代表\,
最终上条语句的意思是,把真实内容中的\\都替换成\
在理解以上情景时请以调试时的红框中内容为标准,而非System.out.println()时打印出来的内容为标准
使用正则逐行分析提取报文
package com.example.demo2; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 使用正则逐行分析提取报文文本,分析工具 * * @author King */ public class AnalysisTextTool { /** * 读取一个文本 一行一行读取 * * @param path * @return * @throws IOException */ public static List<String> readFile02(String path) throws IOException { // 使用一个字符串集合来存储文本中的路径 ,也可用String []数组 List<String> list = new ArrayList<String>(); FileInputStream fis = new FileInputStream(path); // 防止路径乱码 如果utf-8 乱码 改GBK eclipse里创建的txt 用UTF-8,在电脑上自己创建的txt 用GBK InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); String line = ""; while ((line = br.readLine()) != null) { // 如果 t x t文件里的路径 不包含---字符串 这里是对里面的内容进行一个筛选 if (line.lastIndexOf("---") < 0) { list.add(line); } } br.close(); isr.close(); fis.close(); return list; } public static void main(String[] args) throws Exception { // 文件夹路径 String path = "src/main/java/com/example/demo2/result2.txt"; List<String> scanListPath = readFile02(path); StringBuilder sb = new StringBuilder(); for (int i = 0; i < scanListPath.size(); i++) { String lineData = scanListPath.get(i); Pattern p = Pattern.compile("V7-ISC \\[(.*?)>>>.*?接口中文名#(.*?)#web_isc_data主键#(.*)?#本次交互唯一码#.*?#耗时.*?毫秒\\]#\\[(.*?)秒\\]\\]");//正则 Matcher m = p.matcher(lineData); if (m.find()) { String group1 = m.group(1).trim(); String group2 = m.group(2).trim(); String group3 = m.group(3).trim(); String group4 = m.group(4).trim(); sb.append(group1 + "\t" + group2+ "\t" + group3+"\t" + group4).append("\n"); } else { //System.out.println("未解析到正则对应值"); } } FileTool.writeStringToFile("src/main/java/com/example/demo2/z-20191126091400.txt",sb.toString(),"utf-8",false); } }
我的其它文章
其它文章
正则表达式匹配解析过程探讨分析(正则表达式匹配原理) 浅析正则表达式—(原理篇)
public static void main(String[] args) { System.out.println("--<a>1</a>pp<b>2</b>pp<c>3</c>yy <list><b>4<b></list>--".replaceAll("<a>(.*)</a>|<b>(.*)</b>|<c>(.*)</c>", "$1$2$3")); //bbcc //打印: --1pp2pp3yy <list><b>4<b></list>-- }
Postgresql 正则表达式(转)==>https://www.cnblogs.com/ajianbeyourself/p/5140450.html
后言
正则表达式在处理字符串上确实强大又灵活,但在高并发的压力下,可能还是避免使用,尽量手动自己写字符串处理.