美文网首页
Et Voilà | 明天你是否会想起,昨天你写的正则表达式

Et Voilà | 明天你是否会想起,昨天你写的正则表达式

作者: Sophia大黄 | 来源:发表于2017-05-06 16:54 被阅读0次

    正则表达式,一个基础到不能再基础的概念,甚至很多非CS的人都会识会写。但还真保不准哪天突然就忘了,突然就写不出了,所以捋一捋还是很有必要的。人家没事要走两步,我们呢,没事就写两行。

    正规的定义就不重复了,大家都能找到。正则表达式说白了就是给出一个模版或者说规范,然后看字符串是否匹配这个规范,进而根据结果做下一步处理。

    正则表达式之常用符号

    下面是一些正则表达式一些最常用的符号的解析:

    想要什么?

    [ ], 中括号表示这个位置出现哪些字符是符合规范,可以接受的。它可以嵌套使用。

    表达式 含义
    [123] 这里我需要1,2 或3,其他的不行
    [0-9] 这里我需要数字
    [a-cA-C] 这里我需要a到c或A到C, 也就是两个范围的并集
    [^abc] 除了a,b和c, 其他都可以
    [a-c&&[^bc]] &&两个范围的交集,这里表示a到c交不含b,c,也就是a

    想要几个?

    当你需要更精确的正则时,你有时候会需要定义某一个字符需要出现几次,这也是正则可以实现的。

    表达式 含义
    ... 点表示任意字符,三个点即三个字符,随便啥,但一定要给我三个
    y? y出现一次或零次(x<=1)
    y* y出现零次或多次(x>=0)
    y+ y出现一次或多次(x>=1)
    y{n}? y出现n次(x=n)
    y{n,}? y出现至少n次(x>=n)
    y{n,m}? y出现n到m次(n<=x<=m)

    一头一尾

    正则表达式还可以帮助我们规定一些边界问题,使得匹配更为精确

    表达式 含义
    ^ 行的开头
    $ 行的结尾
    \b 单词边界
    \B 非单词边界

    边界问题还有其他一些表达式,不过使用较少,这里就不全部列举出来了,关于单词边界,后面大黄会举个例子

    黑话暗语

    面对很多复杂但又常用的规范,正则表达式还提供了一些简要的,约定俗成的写法,记住这些可以帮助我们大大简化一些表达式

    表达式 含义
    \d 数字
    \D 非数字
    \s 空白字符
    \S 非空白字符
    \w 单词字符 (单词字符包含"_")
    \W 非单词字符

    正则表达式之举个栗子

    好了,让我们写两行吧。大黄用java来举栗子。首先,java中和正则表达式联系最紧密的三个类非他们莫属:

    • java.lang.String
    • java.util.regex.Pattern
    • java.util.regex.Matcher

    贴上大黄的测试:

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class regExp {
    
        public static void main(String[] args) {
            //用Pattern建立一个模版,这里我们需要正则表达式来设定你想要的规范
            Pattern p = Pattern.compile("[a-z]{3}");
            //引入一个匹配对象,这个就是你想要与模版进行匹配的目标
            Matcher m = p.matcher("abc");
            //通过matches()方法的调用来确认结果
            printResult(m.matches());
            
            //上面的三行代码可以用下面一行代码代替,是不是很简单
            printResult("Test1");
            printResult("abc".matches("[a-z]{3}"));
            
            //来匹配一个Ip地址
            printResult("Test2");
            printResult("192.168.0.aaa".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
            
            //再来个单词边界
            printResult("Test3");
            printResult("Hello world".matches("^H[a-z]{1,3}o\\b.*"));  
            printResult("Helloworld".matches("^H[a-z]{1,3}o\\b.*"));  
        }
        
        public static void printResult(Object o){
            System.out.println(o);
        }
    }
    

    结果是:

    true
    Test1
    true
    Test2
    false
    Test3
    true
    false
    

    在IP地址和单词边界的例子中,可以看到大黄用了"\d"这样的表示方法,而非"\d",这是由于java的转义字符的原因,简单来说就是第一个反斜杠表示第二个反斜杠是反斜杠而不是其他转义字符的一部分。边界例子中第一个返回true第二个是false的原因就是\b的出现,它跟在o后面表示到o为止是一个单词。

    Et voilà!

    相关文章

      网友评论

          本文标题:Et Voilà | 明天你是否会想起,昨天你写的正则表达式

          本文链接:https://www.haomeiwen.com/subject/fygetxtx.html