正则表达式

正则表达式中的常用字符

特殊字符及其操作
特殊字符说明
^边界匹配符:匹配一行的开头,不占用字符
$边界匹配符:匹配一行的结尾,不占用字符
.表示任何单个字符
?前一个字符 0 次或 1 次扩展
*前一个字符 0 次或 无限次扩展
+前一个字符 1 次或 无限次扩展
|指定两项之间任选一项,例 abc | def 表示 abc、def
\用于转义下一个字符
( )分组标记,可将多个表达式合并成一个子表达式,内部只能使用 | 操作符
[ ]字符集,对单个字符给出范围
{m}前一个字符 m 次扩展
{m,n}前一个字符 m-n 次扩展

上述所有的字符为正则表达式中定义的特殊字符,如果要匹配它们字符本身,需要进行转义。特别的在Java中,也是用 \ 来转义,Java中如果要匹配这些特殊字符需要经过两轮转义,即\\,所以在Java中要匹配 \ ,需要\\\\

^ 和 $ 的用法:

例如:

  • [a-z] 可以用来匹配字符串任意位置上的小写字母: “…a…”
  • ^[a-z] 只能匹配字符串行首的小写字母: “a…”
  • [a-z]$ 只能匹配字符串行尾的小写字母: “…a”
  • ^[a-z]$ 只能匹配只有一个小写字母的字符串行中的小写字母: “a”
public static void main(String[] args) {
        // test ^ $
        Pattern pattern1 = Pattern.compile("[a-z]");
        Matcher matcher1 = pattern1.matcher("12a34");
        if (matcher1.find())
            System.out.println(matcher1.group());  // 输出 a
        else
            System.out.println("Not found");

        Pattern pattern2 = Pattern.compile("^[a-z]");
        Matcher matcher2 = pattern2.matcher("12a34");
        if (matcher2.find())
            System.out.println(matcher2.group());
        else
            System.out.println("Not found");      // 输出 Not found

        Pattern pattern3 = Pattern.compile("^[a-z]");
        Matcher matcher3 = pattern3.matcher("a34");
        if (matcher3.find())
            System.out.println(matcher3.group());   // 输出 a
        else
            System.out.println("Not found");

        Pattern pattern4 = Pattern.compile("[a-z]$");
        Matcher matcher4 = pattern4.matcher("12a34");
        if (matcher4.find())
            System.out.println(matcher4.group());
        else
            System.out.println("Not found");    // 输出 Not found

        Pattern pattern5 = Pattern.compile("[a-z]$");
        Matcher matcher5 = pattern5.matcher("12a");
        if (matcher5.find())
            System.out.println(matcher5.group());   // 输出 a
        else
            System.out.println("Not found");

        Pattern pattern6 = Pattern.compile("^[a-z]$");
        Matcher matcher6 = pattern6.matcher("a1");
        if (matcher6.find())
            System.out.println(matcher6.group());
        else
            System.out.println("Not found");   // 输出 Not found

        Pattern pattern7 = Pattern.compile("^[a-z]$");
        Matcher matcher7 = pattern7.matcher("a");
        if (matcher7.find())
            System.out.println(matcher7.group());  // 输出 a
        else
            System.out.println("Not found");
    }
方括号表达式对单个字符的限定
  • 枚举:[abc] 表示 a、b、c中的任意一个字符
  • 范围:[a-z] 表示 a、b、c、…、z中的任意一个字符
  • 排除:[^abc] 表示 除了a、b、c的任意一个字符
  • 交集:[a-z&&[def]] 表示 a-z和def交集中的任意一个字符
  • 并集:[a-c[def]] 表示 a-c和def并集中的任意一个字符,也就是[a-cdef]
预定义字符
预定义子符说明
\d匹配数字,等价于[0-9]
\D匹配非数字
\w匹配所有的单词字符,等价于[0-9A-Za-z_](注意:包括下划线)
\W匹配所有的非单词字符

贪婪匹配和最小匹配

贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。

贪婪匹配
  • 贪婪匹配: 尽可能多的匹配,在第一次匹配成功的前提下,仍向后尝试匹配直至匹配失败终止
  • 属于贪婪匹配的的量词,也叫做匹配优先量词,包括:?*+{m,n}{m,}
最小匹配(非贪婪匹配)
  • 最小匹配:匹配到第一次使表达式成立是即停止匹配
  • 在一些使用NFA引擎的语言中,在匹配优先量词后加上?,即变成属于非贪婪匹配的量词,也叫做忽略优先量词,包括:??*?+?{m,n}?{m,}?
// test 贪婪
String p1= "[a-z]";
String p2= "[a-z]+";
String p3= "[a-z]+?";
Pattern patternT = Pattern.compile(p3);
Matcher matcherT = patternT.matcher("asd");
while (matcherT.find())
    System.out.println(matcherT.group());
/*Output:
p1:
    a
    s
    d

p2:
    asd

p3:
    a
    s
    d
 */

贪婪与非贪婪模式原理

正则表达式中的环视

环视基础

环视只进行子表达式的匹配,不占有字符,匹配到的内容无论true or false都不保存到最终的匹配结果,是零宽度的,环视匹配的最终结果就是一个位置,所以又叫做断言或预搜索。

环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功。

环视分类

环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视。顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件。

  • (?=Expression) : 顺序肯定,表示 如果所在位置右侧字符能够匹配Expression 则 匹配成功,定位到该位置;
  • (?!Expression) : 顺序否定,表示 如果所在位置右侧字符不能匹配Expression 则 匹配成功(即排除能匹配Expression的),定位到该位置;
  • (?<=Expression) : 逆序肯定,表示 如果所在位置左侧字符能够匹配Expression 则 匹配成功,定位到该位置;
  • (?<!Expression) : 逆序否定,表示 如果所在位置左侧字符不能匹配Expression 则 匹配成功(即排除能匹配Expression的),定位到该位置。
环视的通俗理解

环视只是一个判断条件,它的作用就是通过判断把我们带到想要的位置,也就是说你想得到的匹配 or 不匹配某个Expression的位置。

  • 对于顺序肯定环视而言:? 代表未知的判断结果(true or false), ?=Expression代表这个结果 等于 当前位置右侧字符匹配 Expression 返回的结果(true or false),并且返回?的值,即如果当前位置右侧字符匹配 Expression 返回 true,则 ?=true,这个时候整个环视表达式为 true,从而定位到当前字符,代表找到了我们想要的位置。

  • 对于顺序否定环视而言:? 代表未知的判断结果(true or false), ?!Expression代表这个结果 等于 当前位置右侧字符匹配 Expression 返回的结果(true or false)再取反,并且返回?的值,即如果当前位置右侧字符匹配 Expression 返回 false,则 ?=true,这个时候整个环视表达式为 true,从而定位到当前字符,代表找到了我们想要的位置。

  • 对于逆序只是对当前位置左侧字符进行判断,其他分析过程完全相同。

环视示例
  • 匹配小括号中的内容:"(?<=\()[^)]+"
  • 匹配中括号中的内容:"(?<=\[)[^]]+"
  • 匹配大括号中的内容:"(?<=\{)[^}]+"

上面正则表达式中第一个小括号里(?<=\()即逆序肯定环视,其中 Expression 为\( ,因为 (为特殊字符,所以要先转义。这个环视最终的效果是找到在该字符位置左边( 的字符,并返回它的位置,后面的[^)]代表匹配一个不是)的字符,换言之即遇到)就停止,后面的+代表贪婪匹配,对前面的单个字符进行贪婪匹配,即只要条件满足一直匹配下去直到遇到)

// test 逆序肯定
Pattern patternN = Pattern.compile("(?<=\\()[^)]+");  // 注意这里 java 转义要用 //
Matcher matcherN = patternN.matcher("(123 $#%$#^3 adsad)");
if (matcherN.find())
    System.out.println(matcherN.group());  // 输出 123 $#%$#^3 adsad
else
    System.out.println("Not found");

// test 顺序肯定 -- 注意输出多了个 (
Pattern patternS = Pattern.compile("(?=\\()[^)]+");
Matcher matcherS = patternS.matcher("(123 $#%$#^3 adsad)");
if (matcherS.find())
    System.out.println(matcherS.group());  // 输出 (123 $#%$#^3 adsad
else
    System.out.println("Not found");

正则基础之环视详解

经典正则表达式实例

正则表达式含义
^[A‐Za‐z]+$由26个字母组成的字符串
^[A‐Za‐z0‐9]+$由26个字母和数字组成的字符串
^‐?\d+$整数形式的字符串
^[0‐9]*[1‐9][0‐9]*$正整数形式的字符串
[1‐9]\d{5}中国境内邮政编码,6位
[\u4e00‐\u9fa5]匹配中文字符
\d{3}-\d{8}|\d{4}-\d{7}匹配国内电话号码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值