zoukankan      html  css  js  c++  java
  • 重复

    正则表达式第一件能做的事是能够匹配不定长的字符集,而这是其它能作用在字符串上的方法所不能做到的。 不过,如果那是正则表达式唯一的附加功能的话,那么它们也就不那么优秀了。它们的另一个功能就是你可以指定正则表达式的一部分的重复次数。

    我们讨论的第一个重复功能的元字符是  并不匹配字母字符 "*";相反,它指定前一个字符可以被匹配零次或更多次,而不是只有一次。

    举个例子,ca*t 将匹配 "ct" (0 个 "a" 字符), "cat" (1 个 "a"), "caaat" (3 个 "a" 字符)等等。RE 引擎有各种来自 C 的整数类型大小的内部限制,以防止它匹配超过20亿个 "a" 字符;你也许没有足够的内存去建造那么大的字符串,所以将不会累计到那个限制。

    象 * 这样地重复是“贪婪的”;当重复一个 RE 时,匹配引擎会试着重复尽可能多的次数。如果模式的后面部分没有被匹配,匹配引擎将退回并再次尝试更小的重复。

    一步步的示例可以使它更加清晰。让我们考虑表达式 a[bcd]*b。它匹配字母 "a",零个或更多个来自类 [bcd]中的字母,最后以 "b" 结尾。现在想一想该 RE 对字符串 "abcbd" 的匹配。

    StepMatchedExplanation
    1 a a 匹配模式
    2 abcbd 引擎匹配 [bcd]*,并尽其所能匹配到字符串的结尾
    3 Failure 引擎尝试匹配 b,但当前位置已经是字符的最后了,所以失败
    4 abcb 退回,[bcd]*尝试少匹配一个字符。
    5 Failure 再次尝次b,但在当前最后一位字符是"d"。
    6 abc 再次退回,[bcd]*只匹配 "bc"。
    7 abcb 再次尝试 b ,这次当前位上的字符正好是 "b"

    RE 的结尾部分现在可以到达了,它匹配 "abcb"。这证明了匹配引擎一开始会尽其所能进行匹配,如果没有匹配然后就逐步退回并反复尝试 RE 剩下来的部分。直到它退回尝试匹配 [bcd] 到零次为止,如果随后还是失败,那么引擎就会认为该字符串根本无法匹配 RE 。

    另一个重复元字符是 +,表示匹配一或更多次。请注意 和 + 之间的不同; 匹配零或更多次,所以可以根本就不出现,而 + 则要求至少出现一次。用同一个例子,ca+t 就可以匹配 "cat" (1 个 "a"), "caaat" (3 个 "a"), 但不能匹配 "ct"。

    还有更多的限定符。问号 ? 匹配一次或零次;你可以认为它用于标识某事物是可选的。例如:home-?brew 匹配 "homebrew" 或 "home-brew"。

    最复杂的重复限定符是 {m,n}(注意m,n之间不能有空格),其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。举个例子,a/{1,3}b 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "a////b" ,因为有四个。

    你可以忽略 m 或 n;因为会为缺失的值假设一个合理的值。忽略 m 会认为下边界是 0,而忽略 n 的结果将是上边界为无穷大 -- 实际上是先前我们提到的20亿,但这也许同无穷大一样。

    +

    细心的读者也许注意到其他三个限定符都可以用这样方式来表示。 {0,} 等同于 ,{1,} 等同于 +,而{0,1}则与 ? 相同。如果可以的话,最好使用 ,+,或?。很简单因为它们更短也更容易懂。

  • 相关阅读:
    什么叫线程安全?servlet 是线程安全吗?
    SynchronizedMap 和 ConcurrentHashMap 有什么区别?
    CopyOnWriteArrayList 可以用于什么应用场景?
    乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
    当一个线程进入某个对象的一个 synchronized 的实例方 法后,其它线程是否可进入此对象的其它方法?
    一个线程运行时发生异常会怎样?
    用 Java 实现阻塞队列 ?
    在 java 中 wait 和 sleep 方法的不同?
    为什么代码会重排序?
    volatile 有什么用?能否用一句话说明下 volatile 的应用场景?
  • 原文地址:https://www.cnblogs.com/kuihua/p/5970984.html
Copyright © 2011-2022 走看看