正则表达式:定义字符串的模式,用来对字符串进行搜索、编辑或处理文本。

目前的正则表达式引擎大体上可分为不同的两类:DFA和NFA,而NFA又基本上可以分为传统型NFA和POSIX NFA。

DFA Deterministic finite automaton 确定型有穷自动机

NFA Non-deterministic finite automaton 非确定型有穷自动机

Java使用的是传统型NFA引擎。

下面是Java正则表达式的语法字符:

\

将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。\n 匹配换行符。序列 \\\\ 匹配 \\ ,\\( 匹配 (。

^

匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。

$

匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。

*

零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。

一次或多次匹配前面的字符或子表达式。例如,"zo "与"zo"和"zoo"匹配,但与"z"不匹配。 等效于 {1,}。

?

零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。

{n}

n 是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。

{n,}

n 是非负整数。至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o "。"o{0,}"等效于"o*"。

{n,m}

m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。

?

当此字符紧随任何其他限定符(*、 、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o ?"只匹配单个"o",而"o "匹配所有"o"。

.

匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。

(pattern)

匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用""或者""或者""。

(?:pattern)

匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更经济的表达式。

(?=pattern)

执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

(?!pattern)

执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

x|y

匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。

[xyz]

字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。

[^xyz]

反向字符集。匹配未包含的任何字符。例如,"[^abc]"匹配"plain"中"p","l","i","n"。

[a-z]

字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。

[^a-z]

反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。

\b

匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。

\B

非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。

\cx

匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。

\d

数字字符匹配。等效于 [0-9]。

\D

非数字字符匹配。等效于 [^0-9]。

\f

换页符匹配。等效于 \x0c 和 \cL。

\n

换行符匹配。等效于 \x0a 和 \cJ。

\r

匹配一个回车符。等效于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。

\S

匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。

\t

制表符匹配。与 \x09 和 \cI 等效。

\v

垂直制表符匹配。与 \x0b 和 \cK 等效。

\w

匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。

\W

与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。

\xn

匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用 ASCII 代码。

\num

匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。

\n

标识一个八进制转义码或反向引用。如果 \n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。

\nm

标识一个八进制转义码或反向引用。如果 \nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 \nm 前面至少有 n 个捕获,则 n 是反向引用,后面跟有字符 m。如果两种前面的情况都不存在,则 \nm 匹配八进制值 nm,其中 n 和 m 是八进制数字 (0-7)。

\nml

当 n 是八进制数 (0-3),m 和 l 是八进制数 (0-7) 时,匹配八进制转义码 nml。

\un

匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。

正则的匹配过程,通常情况下都是由一个子表达式(可能为一个普通字符、元字符或元字符序列组成)取得控制权,从字符串的某一位置开始尝试匹配,一个子表达式开始尝试匹配的位置,是从前一子表达匹配成功的结束位置开始的。如果匹配到字符串某一位置时整个表达式匹配失败,那么引擎会使正则向前传动,整个表达式从下一位开始重新尝试匹配,依此类推,直到报告匹配成功或尝试到最后一个位置后报告匹配失败。

正则表达式简单的匹配过程:

 代码为pattern为正则表达式对content进行匹配

(1) 基础匹配过程

    public static void main(String[] args) {
        String content = "abc";
 
        String pattern = "abc";
        System.out.println(content.matches(pattern));
    }

匹配过程:       

        首先由字符“a”取得控制权,由“a”来匹配“a”,匹配成功,控制权交给字符“b”;由于“a”已被“a”匹配,所以“b”从位置1开始尝试匹配,由“b”来匹配“b”,匹配成功,控制权交给“c”;由“c”来匹配“c”,匹配成功放回true。

(2)贪婪模式

    public static void main(String[] args) {
        String content = "abc";
 
        String pattern = "ab?c";
        System.out.println(content.matches(pattern));
    }

        量词“?”属于匹配优先量词,在可匹配可不匹配时,会先选择尝试匹配,只有这种选择会使整个表达式无法匹配成功时,才会尝试让出匹配到的内容。这里的量词“?”是用来修饰字符“b”的,所以“b?”是一个整体。

匹配过程:

        首先由字符“a”取得控制权,由“a”来匹配“a”,匹配成功,控制权交给字符“b?”;由于“?”是匹配优先量词,所以会先尝试进行匹配,由“b?”来匹配“b”,匹配成功,控制权交给“c”,同时记录一个备选状态;由“c”来匹配“c”,匹配成功。记录的备选状态丢弃。

    public static void main(String[] args) {
        String content = "abd";
 
        String pattern = "ab?c";
        System.out.println(content.matches(pattern));
    }

匹配过程:

        首先由字符“a”取得控制权,,由“a”来匹配“a”,匹配成功,控制权交给字符“b?”;先尝试进行匹配,由“b?”来匹配“b”,同时记录一个备选状态,匹配成功,控制权交给“c”;由“c”来匹配“d”,匹配失败,此时进行回溯,找到记录的备选状态,“b?”忽略匹配,即“b?”不匹配“b”,让出控制权,把控制权交给“c”;由“c”来匹配“b”,匹配失败。此时第一轮匹配尝试失败。

正则引擎使正则向前传动,由位置1开始尝试匹配,由“a”来匹配“b”,匹配失败,没有备选状态,第二轮匹配尝试失败。

继续向前传动,直到所有尝试匹配失败,匹配结束。此时报告整个表达式匹配失败。

(3)非贪婪模式 

    public static void main(String[] args) {
        String content = "abc";
 
        String pattern = "ab??c";
        System.out.println(content.matches(pattern));
    }

        量词“??”属于忽略优先量词,在可匹配可不匹配时,会先选择不匹配,只有这种选择会使整个表达式无法匹配成功时,才会尝试进行匹配。这里的量词“??”是用来修饰字符“b”的,所以“b??”是一个整体。

匹配过程:

        首先由字符“a”取得控制权,由“a”来匹配“a”,匹配成功,控制权交给字符“b??”;先尝试忽略匹配,即“b??”不进行匹配,同时记录一个备选状态,控制权交给“c”;由“c”来匹配“b”,匹配失败,此时进行回溯,找到记录的备选状态,“b??”尝试匹配,即“b??”来匹配“b”,匹配成功,把控制权交给“c”;由“c”来匹配“c”,匹配成功。

(4)零宽度匹配过程

        所谓零宽断言,简单来说就是匹配一个位置,这个位置满足某个正则,但是不纳入匹配结果的,所以叫“零宽”,而且这个位置的前面或后面需要满足某种正则。

    public static void main(String[] args) {
        String content = "abc";
 
        String pattern = "^(?=[a-z])[a-z0-9] $";
        System.out.println(content.matches(pattern));
    }

        元字符“^”和“$”匹配的只是位置,顺序环视“(?=[a-z])”只进行匹配,并不占有字符,也不将匹配的内容保存到最终的匹配结果,所以都是零宽度的。

        这个正则的意义就是匹配由字母或数字组成的,第一个字符是字母的字符串。

匹配过程:

        首先由元字符“^”取得控制权,从开始位置开始匹配,匹配成功,控制权交给顺序环视“(?=[a-z])”;

“(?=[a-z])”要求它所在位置右侧必须是字母才能匹配成功,零宽度的子表达式之间是不互斥的,即同一个位置可以同时由多个零宽度子表达式匹配,所以它也是从开始位置尝试进行匹配,开始位置的右侧是字符“a”,符合要求,匹配成功,控制权交给“[a-z0-9] ”;

因为“(?=[a-z])”只进行匹配,并不将匹配到的内容保存到最后结果,并且“(?=[a-z])”匹配成功的位置是开始位置,所以“[a-z0-9] ”也是从开始位置开始尝试匹配的,“[a-z0-9] ”首先尝试匹配“a”,匹配成功,继续尝试匹配,可以成功匹配接下来的“b”和“c”,此时右侧已没有字符,这时会把控制权交给“$”;“$”成功匹配结束符,匹配成功。

总结

到此这篇关于Java中正则表达式匹配过程的文章就介绍到这了,更多相关Java正则匹配过程内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Java中正则表达式匹配过程实例详解的更多相关文章

  1. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. ios – 使用大写符号在字符串swift中获取URL的正则表达式

    我尝试在文本中获取URL.所以,在此之前,我使用了这样一个表达式:但是当用户输入带有大写符号的URL时(例如Http://Google.com,它与它不匹配)我遇到了问题.我试过了:但什么都没发生.解决方法您可以使用正则表达式中的i内联标志关闭区分大小写,有关可用正则表达式功能的详细信息,请参阅FoundationFrameworkReference.(?ismwx-ismwx)Flagsetti

  3. ios – 如何在Swift 3中使用正则表达式?

    解决方法我相信.当没有其他选项适用时,将使用.allZeros.因此,使用Swift3,您可以传递一个空的选项列表或省略options参数,因为它默认为无选项:要么请注意,在Swift3中,您不再使用error参数.它现在抛出.

  4. ios – lldb断点在类目标c中的所有方法

    如何使用lldb在ObjectiveC类中的所有方法上自动设置断点?

  5. swift的正则表达式(NSRegularExpression)

    init(_pattern:String){varerror:NSError?

  6. swift 正则表达式运用实例选自《swifter 100个swift开发必备tip 》

  7. Swift截取HTML中的所有图片url

    在Swift中,要从HTML格式的String中截取出所有的img的所有图片url,要截取的url就要匹配url,需要用到正则表达式。

  8. 收藏swift正则表达式的各种验证

    1.验证邮箱classfuncvalidateEmail(email:String)->Bool{varemailString="[A-Z0-9a-z._%-]@[A-Za-z0-9.-]\\.[A-Za-z]{2,4}"varemailPredicate=nspredicate(format:"SELFMATCHES%@",emailString)returnemailPredicate.eva

  9. Swift3.0-正则表达式 &lt;待续&gt;

    贡献者:赵大财博客:https://my.oschina.net/zhaodacaiGitHub:https://github.com/zhaodacai邮箱:zhaodacai@yeah.comQQ:327532817=============================先直接来代码:NSRegularExpression.OptionscaseInsensitive不区分大小写allowC

  10. 迅速 – IBInspectable创建一个下拉和更好的组织

    简而言之,我想创建一个@IBInspectable属性,使您可以在故事板中从下拉菜单中选择一系列的内容.另外如果有办法创建分隔符,更好地组织IBInspectables,我想知道这是否也可能.在我的示例中,我想为电话号码创建正则表达式字符串,以便当我去故事板时,我可以在下拉菜单中选择“电话号码”项,而不是输入正则表达式字符串.目前,我已经将一个TextField子类化,以便我可以将更多的IBIns

随机推荐

  1. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  4. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  5. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  6. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  7. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  8. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Spring JdbcTemplate执行数据库操作详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下

返回
顶部