正则表达式问题清单
正则表达式规则
- 正则表达式
正则表达式是一种特殊的字符串模式,用于匹配一组字符串
贪婪量词
“*”(贪婪) 重复零次或更多
“+”(懒惰) 重复一次或更多次
“?”(占有) 重复零次或一次
“{n}” 重复n次
“{n,m}” 重复n到m次
“{n,}” 重复n次或更多次
懒惰限定符
“*?” 重复任意次,但尽可能少重复
“+?” 重复1次或更多次,但尽可能少重复
“??” 重复0次或1次,但尽可能少重复
“{n,m}?” 重复n到m次,但尽可能少重复
“{n,}?” 重复n次以上,但尽可能少重复
元字符
“^” :^会匹配字符串的起始位置
" " : " : ":会匹配字符串的结尾
“\w”:匹配字母,数字,下划线.
“\d”: 匹配数字
“\b” : 匹配单词边界
“\s”:匹配空格
[a-z]匹配a至z的所有字母
几种反义
写法很简单改成大写就行了,意思与原来的相反,这里就不举例子了
“\W” 匹配任意不是字母,数字,下划线 的字符
“\S” 匹配任意不是空白符的字符
“\D” 匹配任意非数字的字符
“\B” 匹配不是单词开头或结束的位置
“[^abc]” 匹配除了abc以外的任意字符
捕捉分组
String line = “This order was placed for QT3000! OK?”;
String pattern = "(\D*)(\d+)(.)";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
则打印: m.group(0),m.group(1),m.group(2) ,m.group(3)
}
结果如下:【0组是整个字符串,1是匹配3000以前的,剩下的就是3000! OK?,2组就是在3000! OK?的基础上进行匹配,3组把3000匹配了,4组就是在! OK?里面去继续匹配字符】
正则表达式中的字符含义
字符描述:
^ :匹配输入的开始位置。
\:将下一个字符标记为特殊字符或字面值。
* :匹配前一个字符零次或几次。
+ :匹配前一个字符一次或多次。
(pattern) 与模式匹配并记住匹配。
x|y:匹配 x 或 y。
[a-z] :表示某个范围内的字符。与指定区间内的任何字符匹配。
\w :与任何单词字符匹配,包括下划线。
$ :匹配输入的结尾。
匹配邮箱和电话号码
public class Main {
public static void main(String[] args) {
/**
* 合法E-mail地址:
* 1. 必须包含一个并且只有一个符号“@”
* 2. 第一个字符不得是“@”或者“.”
* 3. 不允许出现“@.”或者.@
* 4. 结尾不得是字符“@”或者“.”
* 5. 允许“@”前的字符中出现“+”
* 6. 不允许“+”在最前面,或者“+@”
*/
//电子邮件
String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
Pattern regex = Pattern.compile(check);
Matcher matcher = regex.matcher("d12@.23few.@");
boolean isMatched = matcher.matches();
System.out.println(isMatched);
/* 电话号码
String check = "^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\d{8}$";
Pattern regex = Pattern.compile(check);
Matcher matcher = regex.matcher("13555655606");
boolean isMatched = matcher.matches();
System.out.println(isMatched);
*/
}
}
1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC
正则\1\2和\1的理解
原创liangf05 发布于2018-02-24 14:06:15 阅读数 11910 收藏
展开
正则表达式中
‘\1’ 匹配的是 字符 ‘\1’ 。 (因为 ‘\’ 匹配字符 ‘\’ )
‘\2’ 匹配的是 字符 ‘\2’
单独斜杠的 \1 , \2 就是反向引用了。
‘\1’ 匹配的是 所获取的第1个()匹配的引用。例如,’(\d)\1’ 匹配两个连续数字字符。如33aa 中的33
‘\2’ 匹配的是 所获取的第2个()匹配的引用。
例如,’(\d)(a)\1’ 匹配第一是数字第二是字符a,第三\1必须匹配第一个一样的数字重复一次,也就是被引用一次。如9a9 被匹配,但9a8不会被匹配,因为第三位的\1必须是9才可以,
‘(\d)(a)\2’ 匹配第一个是一个数字,第二个是a,第三个\2必须是第二组()中匹配一样的,如,8aa被匹配,但8ab,7a7不会被匹配,第三位必须是第二组字符的复制版,也是就引用第二组正则的匹配内容
以此类推
$1表示正则中第一对圆括号内匹配的内容
$2表示正则中第二对圆括号内匹配的内容
链接:https://www.nowcoder.com/questionTerminal/42852fd7045c442192fa89404ab42e92?orderByHotValue=1&page=1&onlyReference=false
来源:牛客网
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int line = scanner.nextInt();
scanner.nextLine();
for (int i = 0; i < line; i++) {
/**
*第一个正则把3个以上的字符换成2个,第二个正则把AABB型换成AAB型
*
*/
System.out.println(scanner.nextLine().replaceAll("(.)\\1+","$1$1").replaceAll("(.)\\1(.)\\2","$1$1$2"));
}
}
}