普通字符
普通字符,也称为字面量 (Literals),是指在正则表达式中直接表示其字面含义的字符。它们没有其他特殊的含义,所见即所得。例如,正则表达式 51job 将匹配字符串中连续出现的 51job 这 5 个字符。
控制字符
一些不可见的控制字符用于匹配特定的格式和布局,这些字符虽然在文本中不可见,但它们在处理文本时起着重要的作用。
\r回车符 (carriage return): 将光标移动到当前行的行首,而不会换到下一行。如果在回车符后继续输出内容,会覆盖当前行之前的内容。\n换行符 (newline): 将光标移动到下一行的开头,而不会回到行首。通常用于表示行与行之间的分隔。\t制表符 (tab): 插入一个水平制表符,通常用于对齐文本。制表符的宽度取决于环境的设置,通常是 8 个字符。\f换页符 (form feed): 将光标移动到下一页的开头。在打印机中,换页符用于指示打印机开始新的一页。\v垂直制表符 (vertical tab): 将光标移动到下一行的垂直制表位置。虽然在现代文本处理中不常用,但在某些特定环境中仍然有其用途。
字符集合
字符集合使用方括号 [] 来定义,用于匹配集合中的任意一个字符。每次匹配的都是单个字符。例如,[abc] 表示匹配小写字母 a、b 或 c 中的任意一个字符。我们还可以使用短横线 - 来表示一个范围,从而简化字符集合的定义。例如,[0-9] 表示匹配任意一个从 0 到 9 的阿拉伯数字。此外,我们还可以用 [^A-Z] 表示匹配除了大写字母 A 到 Z 以外的任何字符。
为了方便使用,正则表达式预定义了一些常用的字符集合,罗列如下:
\d匹配一个数字字符,等价于[0-9],其反义为\D,匹配非数字字符。\w匹配一个单词字符 (字母、数字或下划线),等价于[A-Za-z0-9_],其反义为\W,匹配非单词字符。\s匹配任何空白字符,包括空格、制表符、换页符等,等价于[\t\n\v\f\r\x20],其反义为\S,匹配任何非空白字符。.匹配除换行符\n之外的任何单个字符。
Unicode 字符集合
Unicode 字符集合提供了一种强大的方式来匹配各种字符类型。以下是一些常用的 Unicode 字符集合及其对应的字符范围:
\p{Lower}: 匹配小写字母,相当于[a-z]\p{Upper}: 匹配大写字母,相当于[A-Z]\p{ASCII}: 匹配 ASCII 字符,相当于[\x00-\x7F]\p{Alpha}: 匹配字母字符,相当于[\p{Lower}\p{Upper}]\p{Digit}: 匹配数字字符,相当于[0-9]或\d\p{Alnum}: 匹配字母和数字字符,相当于[\p{Alpha}\p{Digit}]\w: 匹配字母、数字和下划线字符,相当于[\p{Alnum}_]\p{Punct}: 匹配标点符号,相当于[!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]\p{Graph}: 匹配可见字符,相当于[\p{Alnum}\p{Punct}]\p{Print}: 匹配可打印字符,相当于[\p{Graph}\x20]\p{Blank}: 匹配空白字符,相当于[\t\x20]\p{Space}: 匹配空白字符,相当于[\t\n\v\f\r\x20]或\s\p{Cntrl}: 匹配控制字符,相当于[\x00-\x1F\x7F]\p{XDigit}: 匹配十六进制数字字符,相当于[0-9a-fA-F]
此外,还有一些特定于 Java 的 Unicode 字符集合:
\p{javaLowerCase}: 匹配各种语言的小写字母,范围比\p{Lower}更广\p{javaUpperCase}: 匹配各种语言的大写字母,范围比\p{Upper}更广\p{javaWhitespace}: 匹配各种空白字符,范围比\p{Space}更广,包括中文空白字符
其他常见的 Unicode 字符集合包括:
\p{P}: 匹配各种语言的标点符号,范围比\p{Punct}更广\p{Ps}: 匹配开始括号\p{Pe}: 匹配结束括号\p{Pi}: 匹配开始引号\p{Pf}: 匹配结束引号\p{Pc}: 匹配连接字符\p{Pd}: 匹配虚线字符\p{Po}: 匹配其他字符\p{S}: 匹配符号\p{Z}: 匹配分隔符\p{IsHan}: 匹配汉字
量词
量词 (Quantifiers):用于指定前面元素的出现次数。通用的写法是 {n,m},表示至少出现 n 次,但不超过 m 次。以下是几种常用的量词表示方法:
*:匹配 0 次或多次,相当于{0,}+:匹配 1 次或多次,相当于{1,}?:匹配 0 次或 1 次,相当于{0,1}{n}:匹配恰好 n 次{n,}:匹配至少 n 次{,m}:匹配至多 m 次
默认情况下,量词匹配是贪婪模式,即尽可能多地匹配字符。例如,正则表达式 a.*b 在字符串 aabbb 中会匹配整个字符串 aabbb。如果希望匹配尽可能少的字符,可以在量词后面加一个问号 ?,表示非贪婪模式。例如,正则表达式 a.*?b 在字符串 aabbb 中会匹配 aab。
分组与捕获
圆括号 () 用于将多个字符组合成一个整体进行匹配,并支持后续的量词操作。例如,(abc) 将匹配字符串 "abc",这与 [abc] 匹配单个字符不同。如果你希望匹配 "abc" 或 "def",可以使用 (abc|def),其中竖线 | 表示逻辑或。
括号不仅用于分组,还可以捕获匹配的内容,便于后续引用。例如,匹配的内容可以通过 \1 引用。如果你只需要分组而不需要捕获,可以使用非捕获分组 (?:...)。这种方式可以避免不必要的捕获,提高正则表达式的效率。
位置匹配
位置匹配,也称为锚点 (Anchors),用于匹配字符串中的特定位置。它们都是零宽度的,即它们不匹配任何实际字符,只匹配位置。
^匹配字符串的开始。例如,^abc匹配以 "abc" 开头的字符串。$匹配字符串的结束。例如,abc$匹配以 "abc" 结尾的字符串。\b匹配一个单词的边界。例如,\bword\b匹配完整的单词 "word"。
此外,还有一些更高级的零宽度断言:
(?=...)向前肯定预查,匹配括号内表达式在前的位置。例如,a(?=b)匹配 "a" 仅当其后跟着 "b"。(?!...)向前否定预查,匹配括号内表达式在前的位置,但不包括该表达式。例如,a(?!b)匹配 "a" 仅当其后不跟着 "b"。(?<=...)向后肯定预查,匹配括号内表达式在后的位置。例如,(?<=a)b匹配 "b" 仅当其前面是 "a"。(?<!...)向后否定预查,匹配括号内表达式在后的位置,但不包括该表达式。例如,(?<!a)b匹配 "b" 仅当其前面不是 "a"。
转义字符
在正则表达式中,许多字符具有特殊含义,例如量词 *、+、?,锚点 ^、$,括号 ()、[]、{},以及反斜杠 \。如果需要将这些字符视为字面量进行匹配,而不是其特殊含义,可以在它们前面加上反斜杠 \。例如,\+ 匹配字符 "+",也可以放在字符集合中进行匹配,例如 [+] 匹配字符 "+"。
修饰符
i忽略大小写:启用此修饰符后,正则表达式将忽略大小写。g全局搜索:启用此修饰符后,正则表达式将搜索整个字符串中的所有匹配项,而不仅仅是第一个。m多行模式:启用此修饰符后,正则表达式中的^和$将匹配每一行的行首和行尾,而不仅仅是整个字符串的开头和结尾。s.匹配任意字符,包括换行符。u使用 unicode 码的模式进行匹配。