正则入门

首先,大概浏览一下正则的api字典:Pattern类 Matcher类

正则表达式(regular expression,简写为regex、regexp或RE),又称规则表达式。计算机科学的一个概念,描述了一种字符串匹配的模式(pattern),用来检索、替换那些符合某个模式(规则)的文本。查找的某个字符或者子字串、或者对字符串进行分割、或者对字符串一些字符进行替换/删除

正则表达式是匹配模式,要么匹配字符,要么匹配位置。

1.正则基础
正则两种模糊匹配:

      横向模糊匹配:一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。其实现的方式使用量词。如:ab{2,5}c

      纵向模糊匹配:一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。其实现的方式是使用字符组。如:a[123]b

正则字符组:虽叫字符组(字符类),但只是其中一个字符。例如[abc],表示匹配一个字符,它可以是“a”、“b”、“c”之一。

       范围表示法:比如[1-9a-zG-Z]。用连字符"-"来省略和简写。注:连字符有特殊用途,匹配"-"时,要么放在开头,要么放在结尾,要么转义。

       排除字符组:字符组的第一位放"^"(脱字符),表示求反的概念。如[^a-c]:排除a,b,c

       理解一些元字符.:通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号...中的每个点,都可以理解成占位符,表示任何类似的东西。

                                \w和\W:是与非的关系,\w匹配数字字母,\W则是非数字字母.注:很多类似的\d和\D都是这种关系

正则量词:也称重复。

      简写形式:{m,}:至少出现m次。{m}:等价于{m,m},表示出现m次。* 等价于{0,},+ 等价于{1,},? 等价于{0,1}

      贪婪匹配和惰性匹配:量词默认是贪婪的.惰性匹配,量词后面加个问号,问一问你知足了吗?

正则多选分支:支持多个子模式任选其一。 如:(p1|p2|p3),其中p1、p2和p3是子模式,用“|”(管道符)分隔,表示其中任何之一。

        注:分支结构也是惰性的,即当前面的匹配上了,后面的就不再尝试了,如:"abcd"用/abc|adbc/去匹配,得到abc,用/abcd|abc/去匹配,得到abcd

字面量,匹配一个具体字符,包括不用转义的和需要转义的。比如a匹配字符”a”,又比如\n匹配换行符,又比如.匹配小数点。

锚点,匹配一个位置,而不是字符。比如^匹配字符串的开头,又比如\b匹配单词边界,又比如(?=\d)表示数字前面的位置。

分组,用括号表示一个整体,比如(ab)+,表示”ab”两个字符连续出现多次,也可以使用非捕获分组(?:ab)+。

反向引用,比如\2,表示引用第2个分组。

正则操作符: 转义符 \

               括号和方括号 (...)、(?:...)、(?=...)、(?!...)、[...] 

                量词限定符 {m}、{m,n}、{m,}、?、*、+ 

                位置和序列 ^ 、$、 \元字符、 一般字符     

                管道符(竖杠) |

              优先级从上至下,由高到低

所有结构里,用到的元字符总结如下:^ $ . * + ? | \ \/ [ ] { } = ! : - ,

总结:匹配字符,无非就是字符组、量词和分支结构的组合使用。

2.java使用正则
pattern 对象是一个正则表达式的编译表示。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

Matcher 对象是对输入字符串进行解释和匹配操作的引擎。需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

//       1.
        System.out.println("".matches(""));


//      2.
        String s = "2.21";
//        String regEx = "^\\d+(\\.\\d+)?";
        String regEx = "^[0-9]+(\\.[0-9]+)?";//() 域段
        Pattern pat = Pattern.compile(regEx);
        Matcher mat = pat.matcher(s);
        boolean rs = mat.find();
        System.out.println(rs);

//      3.
        String content = "I am noob from runoob.com.";
        String pattern = ".*runoob.*";
        //.点:匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[\s\S]”的模式。
        boolean isMatch = Pattern.matches(pattern, content);
        System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);
        Pattern pattern = Pattern.compile("[, |]+");
        String[] strs = pattern.split("Java Hello World  Java,Hello,,World|Sun");
        for (int i = 0; i < strs.length; System.out.println(strs[i]), i++) ;
        String[] strs2 = pattern.split("Java Hello World  Java,Hello,,World|Sun", 3);
        //limt在{1,strs.length},不在这个范围,则都默认拆分最大数量
        for (int i = 0; i < strs2.length; System.out.println(strs2[i]), i++) ;

        //文字替换
        Pattern p = Pattern.compile("正则表达式");
        Matcher matcher = p.matcher("正则表达式 Hello World,正则表达式 Hello World");
        //替换第一个符合正则的数据
//        System.out.println(matcher.replaceFirst("Java"));
//        System.out.println(matcher.replaceAll("java"));
        StringBuffer sbr = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sbr, "Java");//(置换字符)
            System.out.println(sbr.toString());
        }
        matcher.appendTail(sbr);//最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
        System.out.println(sbr.toString());

javascript使用,支持三个模式

<script>
//var str = "02abc";
var str = "02Abc";
//var patt1 = /^\d+abc$/;
var patt1 = /^[0-9]+abc$/ig;
document.write(str.match(patt1)+"<br/>");


var str2 = "Is is the cost of of gasoline going up up 2 3 2";
//var patt2 = /\b([a-z]+) \1\b/ig;
var patt2 = /\b(\w+) \1\b/ig;
document.write(str2.match(patt2));

//i模式--表示匹配是非大小写敏感的
//g模式--表示匹配是全局的,即在目标字符串中按顺序找到满足匹配模式的所有子串,强调的是“所有”,而不只是“第一个”
//m模式--表示多行查找匹配模式,该模式下,^  $除了匹配整个查找字符串的首位外,还匹配每一行的首位位置。

var str3 = "abcs SDsdD f12";
var reg = new RegExp("[a-z]+","gi");
document.write(str3.match(reg));
</script>

3.java Pattern的八种模式

DOTALL: 表达式’.’可以匹配任意字符(包括行的结束符)。默认情况下,表达式’.’不匹配行的结束符。/r/n Windows。/n Unix/Linux。/r Mac。

UNIX_LINES: 只有’行的结束符’才被认作一行的中止,并且与’.’,’^’,以及’$’进行匹配

COMMENTS: 忽略空白(不是指表达式里的”\s”,而是指表达式里的空格,tab,回车之类)和在结束行之前以 # 开头的嵌入式注释。

MULTILINE: 多行模式。’^’和’$’分别匹配一行和字符串的开始和结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。

LITERAL: 纯文本模式。指定模式的输入字符串被视为文字字符序列。在输入序列中,元字符或转义序列没有特殊意义。CASE_INSENSITIVE和UNICODE_CASE保留它们对匹配的影响。其他的模式变得多余了。

UNICODE_CASE: 规范等价,不同的编码中相同的字符视为相等。如果Unicode的编码和字符的Ascoll码值是一样的,则进行匹配,如A和\u0041

CASE_INSENSITIVE: 对ASCII字符进行不区分大小写匹配。默认情况下,大小写不明感的匹配只适用于US-ASCII字符集。

UNICODE_CHARACTER_CLASS: 只有jdk1.7+才支持,启用了预定义字符类的Unicode版本

String str = "aaa\r\nbbb";
String pattern = ".+";
System.out.println("DOTALL-'.'可以匹配任意字符(包括行的结束符)");
print(str, pattern, 0, "not DOTALL");
print(str, pattern, Pattern.DOTALL, "DOTALL");

System.out.println("UNIX_LINES-只有'行的结束符'才被认作一行的中止,并且与'.','^',以及'$'进行匹配");
print(str, pattern, Pattern.UNIX_LINES, "UNIX_LINES");
System.out.println("test\r123");//将输入光标重置于行的开始处
str = "aaa\rbbb";
print(str, pattern, Pattern.UNIX_LINES, "UNIX_LINES IN WINDOWS");
str = "aaa\r\nbbb";
print(str, pattern, Pattern.UNIX_LINES, "UNIX_LINES IN WINDOWS");

System.out.println("COMMENTS-忽略空白和在以#开头的注释。");
str = "aacba\r\naab ab\r\nbbb";
pattern = "aa.+ b#comment";
print(str, pattern, Pattern.COMMENTS, "COMMENT");// whitespace is ignored.

pattern = ".+b$";
System.out.println("MULTILINE-多行模式^、$分别表示匹配行首和行尾");
print(str, pattern, 0, "not NULTILINE");
print(str, pattern, Pattern.MULTILINE, "NULTILINE");

System.out.println("LITERAL-输入字符串被视为文字字符");
pattern = "bb";
str = "aacbba\r\naab ab\r\nbbb .bb .+bb";
print(str, pattern, Pattern.LITERAL, "LITERAL");
pattern = ".+bb";
print(str, pattern, Pattern.LITERAL, "LITERAL");

System.out.println("CANON_EQ-不同的编码中相同的字符视为相等.");
print("AA", "\u0041", Pattern.CANON_EQ, "CANON_EQ");

System.out.println("UNICODE_CASE-对Unicode字符区分大小写匹配");
print("aa", "\u0041", Pattern.UNICODE_CASE, "UNICODE_CASE");
print("aa", "\u0041", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE, "UNICODE_CASE|CASE_INSENSITIVE");

System.out.println("UNICODE_CHARACTER_CLASS-启用预定义字符类和POSIX字符类的Unicode版本");
print("aaAB", "\\p{Lower}", Pattern.UNICODE_CHARACTER_CLASS, "UNICODE_CHARACTER_CLASS");
print("aaAB", "\\p{Upper}", Pattern.UNICODE_CHARACTER_CLASS, "UNICODE_CHARACTER_CLASS");
print("aaAB啦啦啦", "\\w+", 0, "UNICODE_CHARACTER_CLASS");
print("aaAB啦啦啦", "\\w+", Pattern.UNICODE_CHARACTER_CLASS, "UNICODE_CHARACTER_CLASS");

4.正则表达式实战
1)POSIX字符类型:上面Pattern类中有,也有Unicode 块和类别的类,使用方法同

       //匹配出一个文本里面的所有(英文半角)标点符号
        String pattern = "[-!\"\\#\\$%&'()*+,./:;\\\\<=>?@\\[\\]\\^_`\\{\\|\\}~]";
        String str = "1~2-6,C#,1+2=3;@qq.com2^3functon(){}/\\";
        System.out.println("-------------文本里面的所有(英文半角)标点符号-----------------------------");
        print(str, pattern, 0);
//        print(str, "\\\\", 0);
        System.out.println("-------------文本里面的所有(英文半角)标点符号-POSIX字符类来实现------------");
        print(str, "\\p{Punct}", 0);
        print("aa环保部", "\\p{L}+", 0);

2)电话的正则

5.正则优化
正则表达式匹配字符串的这种方式,有个学名,叫回溯法。

回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步(即 回溯),从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。(见百度)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值