匹配单个字符

  • “.”可以匹配任意的 单个 字符、英文字母、数字,以及它本身。

  • 有的时候,我们不想让“.”去匹配任何的字符,仅仅想让它匹配“.”这一单个字符,也就是仅匹配它本身。此时,可以使用“.”来对它进行转义。

  • 正则表达式提供字符组它的语法是 “[dt]”。中括号是特殊标记,用以划定属于组内的字符的界限,它所代表的含义是:“匹配d或者t”。 字符组虽然由多个字符构成,但它仍只匹配单个字符,而字符组能够匹配的单个字符,即是它定义中的字符(“[]”内的字符)。“[]”本身不进行字符匹配,它仅仅划定字符组边界。

  • 在字符组中可以使用区间,不一定非要将匹配写成“[0-9]”,完全可以根据需要写成“[0-3]”,它将仅匹配“0,1,2,3”这个区间。起始字符 和 结束字符,依据的是它的 ASCⅡ值的大小,即是说,将会匹配其ASCⅡ码位于 起始字符 和 结束字符 的ASCⅡ之间的所有字符(包含起始、结束字符)。另外,如果起始字符的ASCⅡ值大于结束字符的ASCⅡ值,例如,如果你写成“[3-0]”,则会出错,导致匹配失败。

  • 如果要在字符组(“[”“]”内)中匹配“-”,需要使用转义符,写法是“-”; 而在“[”“]”以外,“-”变成了一个普通字符,无需再进行转义。

  • 反义字符组。有的时候,我们需要匹配“除了某些字符以外”的其他字符,这时候,我们可以使用反义字符组,其语法是:“[^字符集合]”。 不管是普通字符组还是反义字符组,它总是确定一定以及肯定要匹配一个字符的。当^出现在[]中的时候才代表反义字符。

  • 如果需要匹配特殊字符就需要对特殊字符进行转义。需要使用“\”来进行转义,如果想要匹配“.”字符,只需要“.”进行转义。

  • 如何匹配回车换行,“\t”:Tab建、“\r”:回车、“\n”:换行。

  • 对于“.”和“[”等来说,它们本身就是元字符,而当给它们前面加上转义字符“\”的时候,它们才代表一个普通字符:“.”匹配字符“.”,“[”匹配字符“[”。

  • 对于“r”和“n”等来说,它们本身只是普通字符,而只有当加上转义字符“\”的时候(变成了“\r”和“\n”),它们才代表着元字符:“\r”匹配空字符回车,“\n”匹配空字符换行。

普通字符转义后代表的元字符表如下:

元字符 匹配描述
\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] 相同(即非空格)
\b 写在字符前代表以某个字符开头,写在字符后面代表以某个字符结尾。
\B 写在字符前代表不以某个字符开头,写在字符后面代表不以某个字符结尾。

匹配多个字符

  • 匹配一个或多个字符:“+”,例如:j+,表示匹配至少j或者jj或者jjj等等这样的字符串。

  • 匹配零个或多个字符:*”,例如:j*,表示匹配没有j或者多个j重复的字符串。

  • 匹配零个或一个字符:“?”,例如:j?,表示匹配没有j,或者只有一个j。

  • 很明显“+”,“*”,“?”都是元字符,如果需要匹配这样字符需要进行\+,\*,\?,进行转义操作进行匹配。

  • 匹配指定数目的字符:正则表达式中,可以在 单个字符(比如“j”)、字符组(比如“[abcde]”)、特定字符类型(比如“\d”)、单个任意字符(即“.”) 后面加“{数字}”,来表示匹配零个或多个字符组成的字符串。例如:使用“\d{3}”,可以匹配从 000 到 999,这1000个数。而使用“a{6}”,则可以匹配“aaaaaa”(也只能匹配它,因为“a”是固定字符)。

  • 匹配区间以内数目的字符:正则表达式中,使用“{最小数目,最大数目}”的语法来实现,它的使用方式与上面介绍的匹配固定数目字符的语法相同。

  • 最小数目可以是0,所以 “{0,1}”,相当于 “?”。
    如果不限制最大数目,可以将最大数目设为空,所以{1,}相当于+;而{0,}相当于*

  • ‘{‘和’}’也是元字符,当我们需要对它们进行匹配的时候,使用\进行转义:\{\}

贪婪匹配和惰性匹配

  • 贪婪匹配(greedy):它会匹配尽可能多的字符。它首先看整个字符串,如果不匹配,对字符串进行收缩;遇到可能匹配的文本,停止收缩,对文本进行扩展,当发现匹配的文本时,它不着急将该匹配保存到匹配集合中,而是对文本继续扩展,直到无法继续匹配 或者 扩展完整个字符串,然后将前面最后一个符合匹配的文本(也是最长的)保存起来到匹配集合中。所以说它是贪婪的。

  • 惰性匹配(lazy):它会匹配尽可能少的字符,它从第一个字符开始找起,一旦符合条件,立刻保存到匹配集合中,然后继续进行查找。所以说它是懒惰的。

语法表如下:

贪婪匹配 惰性匹配 匹配描述
? ?? 匹配0个或1个
+ +? 匹配1个或多个
* *? 匹配0个或多个
{n} {n}? 匹配n个
{n,m} {n,m}? 匹配n到m个
{n,} {n,}? 匹配n到无限大

匹配边界

  • 匹配单词边界:正则表达式中,可以在字符前加“\b”,来匹配其 后面的字符位于字符串首位的字符。字符指:单个字符(比如“j”)、字符组(比如“[abcde]”)、特定字符类型(比如“\d”)、转义过的特殊字符“[” 或者 单个任意字符(即“.”)。
    例如:
    Attention: Zhang is the first name of Zh JimmyZhang.
    \bZ进行匹配结果如下,只匹配的单词开头为Z的。
    Attention: Zhang is the first name of Zh JimmyZhang.

  • 正则表达式中,可以在字符后加“\b”,来匹配其前面的字符位于字符串末位的字符。
    例如:
    The cat scat tered its food all over the room.
    以\bcat\b进行匹配,表示即以c开头并且以t结尾中间有a的字符串yi匹配,结果如下:
    The cat scat tered its food all over the room.

  • 单词边界符号:通常情况下,以空格、段落首行、段落末尾、逗号、句号等符号作为边界,值得注意的是,分隔符“-”也可以作为边界。例如:
    The cat s-cat-tered its food all over the room.
    以\bcat\b进行匹配,结果如下
    The cat s-cat-tered its food all over the room.

  • 边界的相对性:当你对一个普通字符,比如“s”,设定边界的时候,它的边界是诸如空格、分隔符、逗号、句号等。当你对一个边界,比如分隔符“-”或者“,”等,设定边界的时候,它的边界是普通字符。
    如下匹配普通字符:
    aaaaxaaaa aaa-x-aaa
    以\bx\b进行匹配结果为
    aaaaxaaaa aaa-x-aaa
    匹配边界符:
    aaaa,aaaa aaa-,-aaa
    以\b,\b进行匹配结果为
    aaaa,aaaa aaa-,-aaa

  • 匹配非单词边界:\B
    例如:
    The cat scattered its food all over the room.
    以\Bcat\B进行匹配
    The cat scattered its food all over the room.

  • 匹配文本边界
    使用^来匹配文本首,使用$来匹配文本尾。

匹配子模式

  • 在正则表达式中,可以使用“(”和“)”将模式中的子字符串括起来,以形成一个子模式。将子模式视为一个整体时,那么它就相当于一个单个字符。

  • 有的时候,我们要取消某段文字中的加粗、斜体等效果,我们想匹配所有的<b></b> 或者 <i></i>,然后把它们替换成空,仅利用之前的知识,我们只能进行两次匹配和替换,一次是</?b>,一次是</?i>
    在正则表达式中,可以使用“|”将一个表达式拆分成两部分“reg1|reg2”,它的意思是:匹配所有符合表达式reg1的文本 或者 符合表达式reg2的文本。