正则表达式 - 语法之定位符
定位符能够将正则表达式固定到行首或行尾。它们还能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
定位符用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。
正则表达式的限定符有:
字符 |
描述 |
^ |
匹配输入字符串的开始位置,如果设置Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。 |
$ |
匹配输入字符串结尾的位置。如果设置了 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。 |
\b |
匹配一个单词边界,即单词与空格间的位置。 |
\B |
非单词边界匹配。 |
注意:不能将限定符与定位符一起使用。由于在紧靠换行或者字边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。
若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。
匹配字边界稍有不同,但向正则表达式添加了很重要的能力。单词边界是单词和空格之间的位置。非单词边界是任何其他位置。
\b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项。
对于 \B 非字边界运算符,位置并不重要,因为匹配不关心究竟是单词的开头还是结尾。
选择
用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。
其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 '\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 '?:'、'?=' 或 '?!' 来重写捕获,忽略对相关匹配的保存。
反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:
Is is the cost of of gasoline going up up?
上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点:
/\b([a-z]+) \1\b/gi
捕获的表达式,正如 [a-z]+ 指定的,包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。\1 指定第一个子匹配项。字边界元字符确保只检测整个单词。否则,诸如"is issued"或"this is"之类的词组将不能正确地被此表达式识别。
正则表达式后面的全局标记 (g) 指示,将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。表达式的结尾处的不区分大小写 (i) 标记指定不区分大小写。多行标记指定换行符的两边可能出现潜在的匹配。
反向引用还可以将通用资源指示符 (URI) 分解为其组件。假定您想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页/路径:
http://www.w3cschool.cc:80/html/html-tutorial.html
下面的正则表达式提供该功能:
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。第二个括号子表达式捕获地址的域地址部分。子表达式匹配 / 和 : 之外的一个或多个字符。第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。最后,第四个括号子表达式捕获 Web 地址指定的路径和/或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。
将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:
第一个括号子表达式包含"http"
第二个括号子表达式包含"www.w3cschool.cc"
第三个括号子表达式包含":80"
第四个括号子表达式包含"/html/html-tutorial.html"
package javay.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RM6_1 { public static void main(String[] args) { int flag = 0; int i =0; // flag |= Pattern.UNIX_LINES; // 0x0001:单字节处理还是双字节处理 or Windows,体现在\n还是\r\n。 flag |= Pattern.CASE_INSENSITIVE; // 0x0002:忽略大小 // flag |= Pattern.COMMENTS; // 0x0004: flag |= Pattern.MULTILINE; // 0x0008:Multiline 属性 // flag |= Pattern.LITERAL; // 0x0010: flag |= Pattern.DOTALL; // 0x0020:匹配所有字符,级别大于Pattern.UNIX_LINES。 // flag |= Pattern.UNICODE_CASE; // 0x0040: // flag |= Pattern.CANON_EQ; // 0x0080: // flag |= Pattern.UNICODE_CHARACTER_CLASS; // 0x0100:\\u // 按指定模式在字符串查找 String line = "开启 开关闭开 谢开落"; String pattern = "\\b开"; // 创建 Pattern 对象 Pattern r = Pattern.compile(pattern,flag); System.out.println(" pattern(): " + r.pattern()); // 创建 matcher 对象 Matcher m = r.matcher(line); if (m.find( )) { do { System.out.println(" groupCount: " + m.groupCount()); for (i = 0; i <= m.groupCount(); i ++) { System.out.println("Found value: " + m.group(i) ); } System.out.println(" start(): " + m.start()); System.out.println(" end(): " + m.end()); } while(m.find( )); } else { System.out.println("NO MATCH"); } } }
更多精彩--->正则表达式 - 语法之限定符
原文链接:https://www.f2er.com/regex/358651.html