正则表达式
基于java 常用正则
元字符收集基本
其它
正则表达式的匹配原理java使用的是传统型NFA引擎 NFA特性:忽略优先、固化分组、环视、条件判断、反向引用(引用捕获内容) 1.回溯 依次处理各个子表达式或组成元素,遇到需要在两个可能成功的可能中进行选择的时候,会选择其一,同时记住另一个,以备稍后可能的需要。 回溯过程参考图 2.匹配优先 尽可能多的匹配。如使用 // 测试匹配优先
public static void testGreediness() {
String text = "The name "McDonald's" is said "makudonarudo" in Japanese";
String regex = "(".*")";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(text);
System.out.println(m.find()); // true
System.out.println(m.groupCount()); // 1
// 匹配优先。.*会匹配到行末尾,之后回溯一个备用状态(此处就类型被迫交还一个字符)
System.out.println(m.group(1)); // "McDonald's" is said "makudonarudo"
}
// 测试匹配优先2
public static void testGreediness2() {
String text = "The name "McDonald's" is said "makudonarudo" in Japanese";
String regex = "("[^"]*")";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(text);
System.out.println(m.find()); // true
System.out.println(m.groupCount()); // 1
System.out.println(m.group(1)); // "McDonald's"
}
3.忽略优先步步为营。遇到量词,尽可能忽略,先匹配后面的正则部分,若不行,再回头。 public static void testLazyQuantifiers() {
String text = "The name "McDonald's" is said "makudonarudo" in Japanese";
String regex = "(".*?")";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(text);
System.out.println(m.find()); // true
System.out.println(m.groupCount()); // 1
// 忽略优先。.*会先忽略,使用其后面的引号进行匹配,不行的话,回头使用点号匹配一个字符,再如此循环继续。
System.out.println(m.group(1)); // "McDonald's"
}
4.占有优先
5.固化分组
6.环视 在环视结构匹配尝试结束后,不会留下任何备用状态。 四种类型的环视
示例:使用环视分隔数字 public static void lookaround() {
// 1纯数字
String str = "134545756";
// (?:...) 非捕获
String regex = "(?<=d)(?=(?:ddd)+$)";
str = str.replaceAll(regex,",");
System.out.println(str); // 输出134,545,756
// 2非纯数字
str = "134545756$";
regex = "(?<=d)(?=(ddd)+(?!d))";
str = str.replaceAll(regex,756$
}
正则优化技巧1.避免重新编译 示例匹配24小时制时间public static void match24H() {
String str = "23";
String regex = "2[0-3]|[01]?[0-9]"; // 注意尽量不要使用[01]?[0-9]|2[0-3],因为多选结构,会按顺序进行匹配。
System.out.println(str.matches(regex)); // true
}
java中使用捕获的值// 测试代码
public static void testGroup() {
String text = "test456Group";
String regex = "w+?(?<gname>d+)w+";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(text);
System.out.println(m.find());
System.out.println(m.groupCount()); // 分组数量,输出1
System.out.println(m.group(0)); // 完整匹配,输出test456Group
System.out.println(m.group(1)); // 每一组匹配文本,输出456
System.out.println(m.group("gname")); // 使用命名捕获,输出456
}
// 将email转换为url形式
public static void testEmailToUrl() {
String text = "test@gmail.com";
Pattern r = Pattern.compile("b(w[-.w]+@[-w]+(?:.[-w]+)+)b",Pattern.CASE_INSENSITIVE);
Matcher m = r.matcher(text);
text = m.replaceAll("<a href="mailto:$1">$1</a>");
System.out.println(text); // <a href="mailto:chencye@126.com">chencye@126.com</a>
}
区分大小写注意:(?i)中是i而不是叹号 public static void testCaseSensitive() {
String text = "testCaseSensitive";
String regex = "[a-z]+";
System.out.println(text.matches(regex)); // false,默认区分大小写
Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(text);
System.out.println(m.matches()); // true,不区分大小写,作用于全局
String text2 = "testCASE";
String regex2 = "(?i)^[a-z]+$";
System.out.println(text2.matches(regex2)); // true (?i)不区分大小写
String text3 = "test2CASE3Test";
String regex3 = "^[a-z]+d(?i)[a-z]+d[a-z]+$";
System.out.println(text3.matches(regex3)); // true (?i)作用于其它后面部分
String text4 = "test2CASE3Test";
String regex4 = "^[a-z]+d(?:(?i)[a-z]+)d[a-z]+$";
System.out.println(text4.matches(regex4)); // false (?i)作用于局部,可修改为(?i:[a-z]+)非捕获不区分大小写
// (?-i)区分大小写
regex = "(?-i)[a-z]+";
pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
m = pattern.matcher(text);
System.out.println(m.matches()); // false,区分大小写,即使设置了Pattern.CASE_INSENSITIVE
}
匹配及解析链接// 匹配及解析链接
public static void testURL() {
String text = "http://localhost:8080/test/index.jsp?name=chencye&action=test";//
String regex = "(?i)^(?:https?|ftp)://([a-zA-Z]++):?+(d*+)([^?s]++)??+((?:[^=s]++=?+[^=&]?+&?+)*+)$";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(text);
System.out.println(m.matches()); // true
m.reset();
System.out.println(m.find()); // true
System.out.println(m.groupCount()); // 4
String host = m.replaceAll("$1");
System.out.println("host: [" + host + "]"); // host: [localhost]
String port = m.replaceAll("$2");
System.out.println("port: [" + port + "]"); // port: [8080]
String path = m.replaceAll("$3");
System.out.println("path: [" + path + "]"); // path: [/test/index.jsp]
String params = m.replaceAll("$4");
System.out.println("params:[" + params + "]"); // params:[name=chencye&action=test]
}
参考正则表达式30分钟入门教程 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |