1. Базовый обзор грамматики
символ | значение | пример | Пример описания | Другие примеры |
---|---|---|---|---|
\\b |
Соответствует границе целевой строки. Граница относится к концу строки или перед пробелом. | wang\\b |
граница соответствия Вана | |
\\B |
Сопоставить неграничную целевую строку | wang\\B |
Матч безграничного Вана | |
\\d和\\D ,\\w和\\W |
\\d和\\D означает [0-9] сумму [^0-9] , \\w和\\W означает [0-9a-zA-Z] сумму[^0-9a-zA-Z] |
|||
` | ` | Совпадение|Выражение до или после | аб|cd | Сопоставьте ab или cd |
? |
? Работает только с ближайшим к нему персонажем. | |||
(?!) |
a(?i)bc |
Сопоставление символов abc, abc не чувствителен к регистру, только b не чувствителен к регистру | ||
`` | ||||
`` | ||||
`` | ||||
`` |
Базовый тест по грамматике:
public static void main(String[] args) {
String content = "a1_2\n1c_8挖";
// String regStr = "[a-z]";//匹配a-z之间任意一个字符
// String regStr = "[^a-z]";//匹配不在a-z之间任意一个字符
// String regStr = "//D";//匹配不是数字的任意一个字符
// String regStr = "\\w";//匹配数字、字母(大小写)、下划线的任意一个字符;等价于[a-zA-z0-9_]
// String regStr = "[a-zA-z0-9.]";
// String regStr = ".";//匹配除\n之外的所有任意一个字符
// String regStr = "\\s";//匹配空白字符(包括空格、制表、回车)
// String regStr = "[abcd]";//匹配在abcd中的任意一个字符
// String regStr = "";//匹配abc字符,abc不区分大小写,只有b不区分大小写:"a((?i)b)c"
//String regStr = "\\d|挖"; //选择匹配符
//String regStr = "_(?!.*_)"; //选择匹配符
String regStr = "(_)(\\d)"; //选择匹配符
//创建pattern是制定大小写不敏感
Pattern pattern = Pattern.compile(regStr/*,Pattern.CASE_INSENSITIVE*/);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println("找到字符串【"+matcher.group(0)+"】符合条件");//输出匹配到的整个字符串
System.out.println("找到字符串【"+matcher.group(1)+"】符合条件");//输出匹配到的第一个分组
System.out.println("找到字符串【"+matcher.group(2)+"】符合条件");//输出匹配到的第二个分组
System.out.println("起始位置:"+matcher.start());
System.out.println("结束位置:"+matcher.end());
}
}
//输出
找到字符串【_2】符合条件
找到字符串【_】符合条件
找到字符串【2】符合条件
起始位置:2
结束位置:4
找到字符串【_8】符合条件
找到字符串【_】符合条件
找到字符串【8】符合条件
起始位置:7
结束位置:9
2. Группировка
Группы делятся на захватывающие и незахватывающие, экономичнее будет не захватывать, поэтому если нет необходимости захватывать, то и захватывать не нужно.
(1) Пример группы захвата
public static void main(String[] args) {
String content = "industry1551jkh4546askindustriesldsk4444";
String regStr = "(?<thisaname>\\d\\d)\\d\\d";
//创建pattern是制定大小写不敏感
Pattern pattern = Pattern.compile(regStr/*,Pattern.CASE_INSENSITIVE*/);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println("找到:"+matcher.group(0));
System.out.println("找到[通过索引]:"+matcher.group(1));
System.out.println("找到[通过组名]:"+matcher.group("thisaname"));
}
}
//输出
找到:1551
找到[通过索引]:15
找到[通过组名]:15
找到:4546
找到[通过索引]:45
找到[通过组名]:45
找到:4444
找到[通过索引]:44
找到[通过组名]:44
(2) Группировка без захвата
public static void main(String[] args) {
String content = "industry1551jkh4546askindustriesldsk4444wwq你好,wwqhello,wwqisagunis";
//(1)
String regStr = "industr(y|ies)";//分组会被捕获
//(2)
//String regStr = "industr(?:y|ies)";//分组不被捕获,效果和「industr(y|ies)」一样只是不捕获
//(3)
//String regStr = "wwq(?=hello|is)";//分组不被捕获。只匹配包含分组条件的前面的匹配字符,此处为匹配后面为hello或者is的wwq
//(4)
//String regStr = "wwq(?!hello|is)";//分组不被捕获。只匹配包含分组条件的前面的匹配字符,此处为匹配后面不为hello或者is的wwq
//创建pattern是制定大小写不敏感
Pattern pattern = Pattern.compile(regStr/*,Pattern.CASE_INSENSITIVE*/);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println("找到:"+matcher.group(0));
}
}
//输出
(1)对应输出:matcher.group(1)输出y或ies
找到:industry
找到:industries
(2)对应输出:matcher.group(1)异常
找到:industry
找到:industries
(3)对应输出:matcher.group(1)异常
找到:wwq
找到:wwq
(4)对应输出:matcher.group(1)异常
找到:wwq
3. Жадное сопоставление
String str="abcaxc";
Patter p="ab.*c";
默认是贪婪匹配,匹配到的字符是abcaxc
若p改为ab.*c?
则改为非贪婪匹配,匹配到的字符是abc
4. Обратная ссылка
После захвата содержимого скобок его можно использовать после скобок, что называется обратной ссылкой. Ссылки такого типа могут находиться как внутри выражения, так и вне выражения.Используются внутренние обратные ссылки \\分组号
и внешние обратные ссылки.$分组号
public static void main(String[] args) {
String content = "我..........我要要....要....学学学....编程!";
String regStr = "\\.";
//创建pattern是制定大小写不敏感
Pattern pattern = Pattern.compile(regStr/*,Pattern.CASE_INSENSITIVE*/);
//将...去掉
//Matcher matcher = pattern.matcher(content);
//content = matcher.replaceAll("");
content = content.replaceAll(regStr, "");
System.out.println(content);
/*
1. "(.)\\1+",首先匹配出重复的字:(我)我,(要)要要,(学)学学
2. 将其替换为分组中的字,即 我我-->我,要要要-->要,学学学-->学
*/
String res = Pattern.compile("(.)\\1+"/*内部反向引用*/).matcher(content).replaceAll("$1"/*外部反向引用*/);
System.out.println(res);
}
//输出
我我要要要学学学编程!
我要学编程!
5. 0 широких утверждений
Утверждения нулевой ширины используются для определения того, выполняются ли условия продолжения сопоставления. Сами по себе они не соответствуют строкам.
символ | иллюстрировать | пример | Пример описания | |
---|---|---|---|---|
?=exp |
Остановитесь, когда опыт совпадет | |||
?!exp |
Остановиться, если опыт не соответствует | |||
?<=exp |
Продолжить, если опыт совпадает | |||
?<!exp |
Если опыт не совпадает, продолжайте |
(1)?=exp
Например, чтобы сопоставить содержимое готовки, пения и выполнения, берется только содержимое готовки, пения и делания. В этот момент для сопоставления можно использовать выражение [a-z]*(?=ing)
приращения
Примечание. Шаги выполнения утверждения просмотра вперед следующие: сначала найдите первое значение с правого конца строки, которая должна быть сопоставлена (то есть выражение в утверждении просмотра вперед), а затем сопоставьте выражение перед ним. если совпадение возможно, то сопоставьте, что соответствует жадной природе регулярности.
public static void main(String[] args) {
String str = "755iwat888iwat";
String regexp = "\\d*(?=iwat)";//匹配到exp就停止
Matcher matcher = Pattern.compile(regexp).matcher(str);
while (matcher.find()){
System.out.println(matcher.group(0));
}
}
//输出
755
//解析,遇到第一个iwat就不再继续往下匹配了
(2)?<=exp
Например, (?<=abc).*
оно может соответствовать defg в abcdefg.
Примечание. Позднее утверждение является полной противоположностью утверждения просмотра вперед. Шаги его выполнения следующие: сначала найдите первый abc с крайнего левого конца строки, которая должна быть сопоставлена (то есть выражение в утверждении просмотра вперед ), а затем сопоставьте следующее выражение. Если оно не может быть сопоставлено, продолжайте поиск второго abc, а затем сопоставьте строку после второго abc. Если оно может быть сопоставлено, оно будет сопоставлено.
public static void main(String[] args) {
String str = "755iwat888iwat999";
String regexp = "(?<=iwat)\\d*".trim();//只匹配iwat后面的连续数字
Matcher matcher = Pattern.compile(regexp).matcher(str);
while (matcher.find()){
System.out.println(matcher.group(0).trim());
}
}
//输出
888
999
(3) ?!exp
(и ?=exp
наоборот)
Например, (?!exp) представляет позицию перед "exp". Если "exp" не соответствует истине, сопоставить эту позицию; если "exp" истинно, оно не будет соответствовать.
Пример 1:
public static void main(String[] args) {
String str = "755iwat888iwat888999";
String regexp = "888(?!.*888)".trim();//最后一次出现的888
Matcher matcher = Pattern.compile(regexp).matcher(str);
while (matcher.find()){
System.out.println(matcher.group(0));
System.out.println(matcher.start());
}
}
//输出
888
14
Пример 2:
public static void main(String[] args) {
String str = "755iwat888iwat888999";
String regexp = "[0-9]*(?!iwat)".trim();//匹配后面不是iwat的连续数字
Matcher matcher = Pattern.compile(regexp).matcher(str);
while (matcher.find()){
System.out.println(matcher.group(0));
//System.out.println(matcher.start());
}
}
//输出
75
88
888999
(4)?<!exp
Вместо ?<=exp
этого поставьте его впереди и используйте
public static void main(String[] args) {
String str = "755iwat888iwat888999";
String regexp = "(?<!iwat)[0-9]*".trim();//匹配前面不是iwat的连续数字,应是755,88,88999
Matcher matcher = Pattern.compile(regexp).matcher(str);
while (matcher.find()){
System.out.println(matcher.group(0));
//System.out.println(matcher.start());
}
}
//输出
755
88
88999
6. Часто используемые API
// Pattern类的方法
0. Pattern.compile(regStr/*,Pattern.CASE_INSENSITIVE*/)//返回一个Pattern
1. Pattern.matches(regStr,str)//判断模式能否将字符串整体匹配出来,返回一个boolean
System.out.println(Pattern.matches(regStr,content));
2. Pattern.matcher(content)//返回一个Matcher
// Matcher类的方法
3. Matcher.group(0)//返回匹配到的第0个分组
4. matcher.start()//返回匹配到字符串的开始位置
5. matcher.end()
6. matcher.find()//是否有匹配到的字符串的部分序列
7. matcher.matches()//字符串是否从头到尾完全匹配了(matches方法会吞掉一个matcher匹配的分组)
8. matcher.replaceAll(str)//将匹配到的字符串全部替换为str,返回替换后的字符串
//String
9. str.replaceAll(regex,replacement)//使用replacement替换str中匹配的regex部分,返回替换后的字符串
10. str.matches(regex)//等价于Pattern.matches(regex, str),返回boolean
11. str.split(regex)//按照匹配的regex部分对str进行分割,返回一个字符数组,返回的数组中不包括匹配到的部分