美国上市公司,专注Java培训22年

Java正则表达式基础知识--5个学习步骤


Java正则表达式基础知识--5个学习步骤

正则表达式学习步骤:

1. 了解正则表达式概念及基本构造元素(本文目标);

2. 通过练习能够编写出准确的可读性较好的正则表达式,熟悉常用正则表达式;

3. 理解正则引擎的内部机制及实现,能够分析正则表达式的效率;

4. 能够编写效率更高的正则表达式(以准确性和可读性为前提);

5. 能够运用正则表达式去处理复杂的文本处理问题。

一、 概述

1. 正则表达式是一个字符序列,用来描述文本的模式结构的表达式,亦可看做一门“微型语言”。因此,尤其适用于文本处理。

2. 一个文本模式可能有多种正则表达式写法,有的简单清晰,有的快速但复杂,有的功能全面,有的兼容性好,要多多尝试加以权衡。

3. 正则表达式是“文本内匹配”。

4. 正则表达式的准确性: 匹配期望的文本,同时不匹配不期望的文本。

比如, 匹配三位数,可使用\d{3},但这样会匹配001这样的数,准确的写法应是: [1-9]\d{2}

5. 匹配分析的思路最好采用“逐字符方式”。

比如 note 匹配一个n紧接着一个o紧接着一个t紧接着一个e, 而不是匹配单词"note"。

二、 基本元素

1. 普通字符: 除 *, ? , \, (, ), [, ], -, . , +, ^, $, {, } , 以外的字符匹配它自身, 比如 a 匹配 a

2. 点号 . : 匹配任意不包括换行符的单个字符。比如, sa. 可匹配 sat, sa*, sa[ 等。

3. 字符组[characters] :匹配字符组中指定字符集合中的任意单个字符: 比如 [abc] 将匹配 a 或 b 或 c , ca[ptb] 将匹配 cap, cat 或 cab。

4. 排除性字符组[^characters] : 匹配字符组中指定字符集合之外的任意单个字符:

比如, [^abc] 将匹配除了 a,b,c 之外的任意单个字符。

ca[^ptb],将匹配 caX 的文本,除了 cap, cat, cab, 注意,这里是匹配一个非指定的字符,而不是不匹配。

5. 范围字符组: [char1-char2] 将匹配从char1 到 char2 之间的任意单个字符(按照ASCII编码)。

比如, [a-z] 匹配任意小写字符; [A-Z] 匹配任意大写字符 ; [0-9] 匹配任意数字; [a-zA-Z0-9] 匹配任意大小写字符或数字。

6. 特殊字符: 凡是在正则式中具有特殊含义的字符,要匹配字符本身(将其作为普通文本)都必须使用反斜线 \ 进行转义;通常需要转义的字符有: . + * ? { } [ ] ( ) - \ ^ $。

比如, 匹配 . 的正则式是 \. , 匹配 \ 的正则式是 \\ , 匹配 ( 的正则式是 \( ;要匹配 (ab) 的正则表达式是 \(ab\) ; 要匹配 a? 的表达式是 a\? ; a? 将匹配空或单个a。

7. 匹配空白字符:

\f 换页 \n 换行 \r 回车 \t 制表符 \v 垂直制表符 \s 匹配任意空白符,包括上述任意一种

8. 字符类: <==> 等价于

\d <==> [0-9] 任意单个数字 \D <==> [^0-9] 任意单个的非数字字符

\w <==> [a-zA-Z0-9_] \W <==> [^a-zA-Z0-9_]

\s <==> [\f\n\r\t\v ] \S <==> [^\f\n\r\t\v ]

9. POSIX 字符类: 例如: [:digit:] <==> [0-9] ; [:alpha:] <==> [a-zA-Z] ; [:alnum:] <==> [a-zA-Z0-9]

具体应用时要再加一层括号,比如 TEST[[:digit:]] 匹配 TEST0 - TEST9。

三、 匹配元素组合:

下面 X, Y 都可以是一个子表达式

1. 顺序结构 XY: 匹配 X 后紧跟 Y 的文本,比如 [0-9][a-z] 匹配 数字后跟小写字母的文本, 7z, 0x 等, 但不匹配 ap, 77。

2. 多选分支结构X|Y: 匹配 X 或者 Y ,比如 [0-9]|[a-z] 匹配数字或小写字母,相当于 [0-9a-z]。

X|Y 是一种多选分支结构,在构造复杂正则表达式中有重要作用。

3. 匹配量词:

匹配一个或多个 X : X+ ; 例如 s/d+ 匹配 s后跟至少一个数字, s9, s34, s235, ...

匹配零个或多个 X : X* ; 例如 s/d* 匹配 s后跟空或者至少一个数字, s, s9, s34, s235, ...

匹配零个或一个 X : X? ; 例如 https? 匹配 http 或 https

匹配恰好 m 个 X : X{m} ; 例如 s/d{4} 匹配 s0000, s1234, 但不匹配 s234, s23445

匹配至少 m 个 X : X{m,} ; 例如 s/d{2,} 匹配 s12, s123, 但不匹配 s1

匹配至少 m 个 但不超过 n 个X : X{m,n} ; 例如 s/d{2,4} , 匹配 s12, s123, s1234, 但不匹配 s1, s12345

4. 子表达式 (X): 将 X 作为一个子表达式,紧邻的匹配量词将作用于 X 整体,而不是 X 中的单个字符。

例如 (s\d){3} 匹配 s1s1s1 ,而不匹配 s111

5. 贪婪匹配: 默认匹配模式是“贪婪型匹配”,即匹配尽可能多的文本。

例如, You make me lost.

正则式 .* 中的 .* 将 从 Y 前面的空格一直匹配到末尾的换行符之前,而不会在第一个停下来。

6. 位置匹配:

[1] \b 单词边界 \B 非单词边界。

文本: The captain wore his cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.

正则式: cap ; \bcap ; cap\b ;\bcap\b ;\Bcap ;cap\B ; \Bcap\B

[2] ^ 匹配文本起始 $ 匹配文本末尾

例如 ^[a-z]123 将匹配以小写字母开头后跟123的文本。匹配文本 a123 而不是 slh a123 。

[a-z]123$ 将匹配以小写字母后跟123结尾的文本。匹配文本 sss d123 而不是 sdf123dss 。

7. 捕获功能: 使用括号将一个子表达式匹配的文本进行捕获,后面可在模式或处理中对捕获的文本进行引用或处理。

((regex1)-(regex2))-(regex3) \n 引用被捕获的第 n 个文本; n 按左括号出现的顺序进行标识\0 表示匹配的整个文本 \1 ref= ((regex1)-(regex2)) ; \2 ref= (regex1) ; \3 ref= (regex2) ; \4 ref= (regex3)

在替换文本时可以使用 $1, $2, $3, $4 分别引用 \1, \2, \3, \4 捕获的文本。

比如, (\d{3}) mygod(\1) 必须匹配 三位数字mygod三位数字 的模式, 并且,后面三位数字必须与前面三位数字完全相同。

8. 回溯引用: 相同匹配的概念, 匹配在多处出现的相同文本。

比如要匹配<h1>hello</h1>中的<h1>...</h1>,使用正则式 <([Hh][1-6])>.*?<\1> ,

这里, \1 可以捕获 ([hH][1-6]) 所得到的结果,从而起到对应的效果,以免匹配到23的不合 法文本。

文本:

<h1>HELLO WORLD</h1>

<h2>WA O</h2>

<h3>YEAH</h3>

正则式: <[Hh][1-6]>.*? </[Hh][1-6]><([Hh][1-6])>.*?<\1>

9. 前后查找: 更灵活的位置匹配

(?=right-regex) : 表示右边字符序列匹配 right-regex 的位置; (?<=left-regex) : 表示左边字符序列匹配 left-regex 的位置。

(?!right-regex): 表示右边字符序列不匹配 right-regex 的位置; (?<=!left-regex) : 表示左边字符序列不匹配 left-regex 的位置。

比如: 要匹配 scatter locate rocate 中 后面紧邻 e 的 cat,使用 cat(?=e), 注意,这里并不会捕获e,而是用e作为捕获 cat 的定位信息。

要匹配前面是 s 的cat, 使用 (?<=s)cat; 同样,这里并不会捕获s,而是将 s 作为捕获 cat 的定位信息。

正则式: ((https?)|(ftp))(?=:)

10. 条件匹配: 当满足某种条件时,才匹配某个模式。

?(back-ref)true-regex 表示,只有当 back-ref 存在时,才会匹配 true-regex;

?(back-ref)true-regex|false-regex 表示,若 back-ref 存在,匹配 true-regex; 若不存在,匹配 false-regex。

例如,要匹配 (123)456-7890 或 123-456-7890 ,而不匹配 (123)-456-7890, 123456-7890,(123-456-7890 等。

这意味着,若123 由括号括住,则不跟 - ; 否则后面紧跟 - ; 正则表达式是: (\()?\d{3}(?(1)\)|-)\d{3}-\d{4}(\()? 表示是否存在 ( , 这里用括号将 ( 作为子表达式,以便于后面回溯引用;

(?(1)\)|-) 表示,如果存在 ( ,则匹配 ) ,否则匹配 -

文本: (123)456-7890 123-456-7890 (123)-456-7890 123456-7890 (123-456-7890

正则式: \(?\d{3}\)?-?\d{3}-\d{4} (\()?\d{3}(?(1)\)|-)\d{3}-\d{4}

四、小结

以上所述就是构造正则表达式的基本知识。编写正则表达式的一个技巧是分而治之、逐步求精,先划分成若干子表达式分别调试成功,再组合起来。要掌握这样一个强大的文本工具,惟有勤加练习,勤于思考求精耳。

感谢大家阅读由java教程栏目分享的“Java正则表达式基础知识--5个学习步骤”希望对大家有所帮助,更多精彩内容请关注Java培训官网

免责声明:本文由小编转载自网络,旨在分享提供阅读,版权归原作者所有,如有侵权请联系我们进行删除


【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!

Java开发高端课程免费试学

大咖讲师+项目实战全面提升你的职场竞争力

  • 海量实战教程
  • 1V1答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • java语言中,char 类型变量是否能保存一个汉字?
    java语言中,char 类型变量是否能保存一个汉字?
    在 Java 语言中,可以使用 char 类型的变量来存储单个的字符,请问是否能用 char 类型的变量来存储一个汉字呢? 详情>>

    2015-10-15

  • 有史以来最牛的一张程序员职业路线图!
    有史以来最牛的一张程序员职业路线图!
    最近在琢磨程序员到底路在何方,经过不断的自虐和代入,终于在迷雾森林中得图一张,看之豁然开朗。独乐乐不如众乐乐,share了: 详情>>

    2018-05-22

  • java中变量和常量有什么区别?
    java中变量和常量有什么区别?
    在使用 Java 语言进行程序设计时,经常需要用到常量和变量来存储信息。请简单叙述变量和常量有什么区别? 详情>>

    2015-10-15

  • short 和 char 类型的取值范围各是多少?
    short 和 char 类型的取值范围各是多少?
    在使用 Java 语言进行程序设计时,经常需要使用 short 型和 char 型存储数值,请简述short 型和 char 型的取值范围各是多少? 详情>>

    2015-10-15

  • Java开班时间

    收起