Board logo

标题: Java Regular Expressions Syntax [打印本页]

作者: qingqing3721    时间: 2011-7-11 02:45     标题: Java Regular Expressions Syntax

一、正则表达式语法
1.1.字符
x 字符 x。例如a表示字符a
\\ 反斜线字符。在书写时要写为\\\\。(注意:由于java在第一次解析时把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1列举到的转义字符,包括1.1的\\,而又带有\的都要写两次)
\0n 带有八进制值 0的字符 n (0 = n = 7)
\0nn 带有八进制值 0的字符 nn (0 = n = 7)
\0mnn 带有八进制值 0的字符 mnn(0 = m = 3、0 = n = 7)
\xhh 带有十六进制值 0x的字符 hh
\uhhhh 带有十六进制值 0x的字符 hhhh
\t 制表符 ('\u0009')
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
\f 换页符 ('\u000C')
\a 报警 (bell) 符 ('\u0007')
\e 转义符 ('\u001B')
\cx 对应于 x 的控制符
1.2.字符类
[abc] a、b或 c(复杂类)。例如[egd]表示包括有字符e、g或d。
[^abc] 任何字符,除了 a、b或 c(否认)。例如[^egd]表示不包括字符e、g或d。
[a-zA-Z] a到 z或 A到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a到 d或 m到 p:[a-dm-p](并集)
[a-z[def]] d、e或 f(交集)
[a-z[^bc]] a到 z,除了 b和 c:[ad-z](减去)
[a-z[^m-p]] a到 z,而非 m到 p:[a-lq-z](减去)
1.3.预定义字符类(注意反斜杠要写两次,例如\d写为\\d)
. 任何字符(与行完毕符可能婚配也可能不婚配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
1.4.POSIX 字符类(仅 US-ASCII)(注意反斜杠要写两次,例如\p{Lower}写为\\p{Lower})
\p{Lower} 小写字母字符:[a-z]。
\p{Upper} 大写字母字符:[A-Z]
\p{ASCII} 所有 ASCII:[\x00-\x7F]
\p{Alpha} 字母字符:[\p{Lower}\p{Upper}]
\p{Digit} 十进制数字:[0-9]
\p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct} 标点符号:!"#$%'()*+,-./:;=?@[\]^_`{|}~
\p{Graph} 可见字符:[\p{Alnum}\p{Punct}]
\p{Print} 可打印字符:[\p{Graph}\x20]
\p{Blank} 空格或制表符:[ \t]
\p{Cntrl} 控制字符:[\x00-\x1F\x7F]
\p{XDigit} 十六进制数字:[0-9a-fA-F]
\p{Space} 空白字符:[ \t\n\x0B\f\r]
1.5.java.lang.Character 类(复杂的 java 字符类型)
\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase()
\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase()
\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace()
\p{javaMirrored} 等效于 java.lang.Character.isMirrored()
1.6.Unicode 块和类别的类
\p{InGreek} Greek 块(复杂块)中的字符
\p{Lu} 大写字母(复杂类别)
\p{Sc} 货币符号
\P{InGreek} 所有字符,Greek 块中的除外(否认)
[\p{L}[^\p{Lu}]] 所有字母,大写字母除外(减去)
1.7.边界婚配器
^ 行的开头,请在正则表达式的末尾处使用^。例如:^(abc)表示以abc开头的字符串。注意编译的时候要设置参数MULTILINE,如 Pattern p = Patternpile(regex,Pattern.MULTILINE);
$ 行的开头,请在正则表达式的完毕处使用。例如:(^bca).*(abc$)表示以bca开头以abc开头的行。
\b 单词边界。例如\b(abc)表示单词的末尾或完毕包括有abc,(abcjj、jjabc 都可以婚配)
\B 非单词边界。例如\B(abc)表示单词的两头包括有abc,(jjabcjj婚配而jjabc、abcjj不婚配)
\A 输入的开头
\G 上一个婚配的开头(个人感觉这个参数没什么用)。例如\\Gdog表示在上一个婚配开头处查找dog如果没有的话则从开头查找,注意如果开头不是dog则不能婚配。
\Z 输入的开头,仅用于最后的完毕符(如果有的话)
行完毕符 是一个或两个字符的序列,标记输入字符序列的行开头。
以下代码被识别为行完毕符:
‐新行(换行)符 ('\n')、
‐前面紧跟新行符的回车符 ("\r\n")、
‐单独的回车符 ('\r')、
‐下一行字符 ('\u0085')、
‐行分隔符 ('\u2028') 或
‐段落分隔符 ('\u2029)。
\z 输入的开头
当编译形式时,可以设置一个或多个标志,例如
Pattern pattern = Patternpile(patternString,Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE);
上面六个标志都是支持的:
‐CASE_INSENSITIVE:婚配字符时与大小写有关,该标志默认只思索US ASCII字符。
‐UNICODE_CASE:当与CASE_INSENSITIVE结合时,使用Unicode字母婚配
‐MULTILINE:^和$婚配一行的末尾和开头,而不是整个输入
‐UNIX_LINES: 当在多行形式下婚配^和$时,只将'\n'看作行终止符
‐DOTALL: 当使用此标志时,.符号婚配包括行终止符在内的所有字符
‐CANON_EQ: 思索Unicode字符的规范等价
1.8.Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰恰 n 次
X{n,} X,至多 n 次
X{n,m} X,至多 n 次,但是不超过 m 次
1.9.Reluctant 数量词
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰恰 n 次
X{n,}? X,至多 n 次
X{n,m}? X,至多 n 次,但是不超过 m 次
1.10.Possessive 数量词
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰恰 n 次
X{n,}+ X,至多 n 次
X{n,m}+ X,至多 n 次,但是不超过 m 次
Greedy,Reluctant,Possessive的区别在于注意仅限于进行.等模糊处理时)
greedy量 词被看作“贪心的”,由于它第一次就读入整个被模糊婚配的字符串。如果第一个婚配尝试(整个输入字符串)失败,婚配器就会在被婚配字符串中的最后一位后退一个字符并且再次尝试,重复这个进程,直到找到婚配或许没有更多剩下的字符可当前退为止。根据表达式中使用的量词,它最后试图婚配的内容是1 个或许0个字符。
但是,reluctant量词采取相反的方式:它们从被婚配字符串的开头末尾,然后逐步地一次读取一个字符搜索婚配。它们最后试图婚配的内容是整个输入字符串。
最后,possessive量词总是读完好个输入字符串,尝试一次(而且只有一次)婚配。和greedy量词不同,possessive从不后退。
1.11.Logical 运算符
XY X 后跟 Y
X|Y X 或 Y
(X) X,作为捕捉组。例如(abc)表示把abc作为一个全体进行捕捉
1.12.Back 引用
\n 任何婚配的 nth捕捉组
捕捉组可以经过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
在表达式中可以经过\n来对相应的组进行引用,例如(ab)34\1就表示ab34ab,(ab)34(cd)\1\2就表示ab34cdabcd。
1.13.引用
\ Nothing,但是引用以下字符
\Q Nothing,但是引用所有字符,直到 \E。QE之间的字符串会原封不动的使用(1.1中转义字符的除外)。例如, ab\\Q{|}\\\\E
可以婚配ab{|}\\
\E Nothing,但是完毕从 \Q末尾的引用
1.14.特殊构造(非捕捉)
(?:X) X,作为非捕捉组
(?idmsux-idmsux) Nothing,但是将婚配标志由 on 转为 off。比如:表达式 (?i)abc(?-i)def 这时,(?i) 翻开不区分大小写开关,abc 婚配
idmsux阐明如下:
‐i CASE_INSENSITIVE :US-ASCII 字符集不区分大小写。(?i)
‐d UNIX_LINES : 翻开UNIX换行符
‐m MULTILINE :多行形式(?m)
UNIX下换行为\n
WINDOWS下换行为\r\n(?s)
‐u UNICODE_CASE : Unicode 不区分大小写。(?u)
‐x COMMENTS :可以在pattern外面使用注解,疏忽pattern外面的whitespace,以及"#"一直到开头(#前面为注解)。(?x)例如(?x)abc#asfsdadsa可以婚配字符串abc
(?idmsux-idmsux:X) X,作为带有给定标志 on - off 的非捕捉组。与上面的相似,上面的表达式,可以改写成为:(?i:abc)def,或许 (?i)abc(?-i:def)
(?=X) X,经过零宽度的正 lookahead。零宽度正先行断言,仅当子表达式 X 在 此位置的右侧婚配时才持续婚配。例如,\w+(?=\d) 表示字母前面跟数字,但不捕捉数字(不回溯)
(?!X) X,经过零宽度的负 lookahead。零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧婚配时才持续婚配。例如,\w+(?!\d) 表示字母前面不跟数字,且不捕捉数字。
(?=X) X,经过零宽度的正 lookbehind。零宽度正后发断言。仅当子表达式 X 在 此位置的左侧婚配时才持续婚配。例如,(?=19)99 表示99前面是数字19,但不捕捉前面的19。(不回溯)
(?!X) X,经过零宽度的负 lookbehind。零宽度负后发断言。仅当子表达式 X 不在此位置的左侧婚配时才持续婚配。例如,(?!19)99 表示99前面不能是19,且不捕捉前面的东东。
(?X) X,作为独立的非捕捉组(不回溯)
(?:X)与(?X)的区别在于(?X)是不回溯的。例如被婚配的字符串为abcm,当表达式为a(?:b|bc)m是可以婚配的,而当表达式是a(?b|bc)m时是不能婚配的,由于当后者婚配到b时,由于曾经婚配,就跳出了非捕捉组,而不再次对组内的字符进行婚配。可以加快速度。 上面这段代码,只输入abm而不会输入abcm。当表达式为a(?:b|bc)m时可以输入abcm。Java代码 Pattern pattern = Patternpile("a(?b|bc)m");  Matcher m = pattern.matcher("abcmkfabm"); while(m.find()){  System.out.println(m.group()); }
Pattern pattern = Patternpile("a(?b|bc)m");Matcher m = pattern.matcher("abcmkfabm");while(m.find()){System.out.println(m.group());}
阐明:回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。 二、例子 1.Java代码 /** * 以非字母和数字作为分隔符,输入数据 * @param input */ public static void testSplit(String input){  //\p{name}: 一个指定的字符类  //Punct :非字母或数字ASCII [\p{Print}\P{Alnum}]  Pattern pattern = Patternpile("\\s*\\p{Punct}\\s*");  if(input ==null || input ==""){  input = "begin | test { split 123456 }00end";  }  String[] tokens = pattern.split(input);  for(String str:tokens){  System.out.println(str);  } }
/*** 以非字母和数字作为分隔符,输入数据* @param input*/public static void testSplit(String input){//\p{name}: 一个指定的字符类//Punct :非字母或数字ASCII [\p{Print}\P{Alnum}] Pattern pattern = Patternpile("\\s*\\p{Punct}\\s*");if(input ==null || input ==""){input = "begin | test { split 123456 }00end";}String[] tokens = pattern.split(input);for(String str:tokens){System.out.println(str);}}
2.Java代码 /** * in:给定形式((1?[0-9])[0-5][0-9]))[ap]m,并且输入11:59am out:Match ((11)59))am */ public static void testGroupMatch() {  Scanner in = new Scanner(System.in);  System.out.println("Enter pattern: ");  String patternString = in.nextLine();   Pattern pattern = null;  try {  pattern = Patternpile(patternString);  } catch (PatternSyntaxException e) {  System.out.println("attern syntax error");  System.exit(1);  }   while (true) {  System.out.println("Enter string to match: ");  String input = in.nextLine();  if (input == null || input.equals(""))  return;  Matcher matcher = pattern.matcher(input);  if (matcher.matches()) {  System.out.println("Match!");  int g = matcher.groupCount();// 获得总的分组数  if (g  0) {  for (int i = 0; i  input.length(); i++) {  for (int j = 1; j = g; j++) {// 第0个分组代表所有的分组,第一个实际分组的索引是1。  if (i == matcher.start(j)) {// 此位置是分组的起始  System.out.print('(');  }  }  System.out.print(input.charAt(i));  for (int j = 1; j = g; j++) {  if (i + 1 == matcher.end(j)) {// 下一个位置是分组的完毕  System.out.print(')');  }  }  }  System.out.println();  }  } else  System.out.println("No match");  } }
/*** in:给定形式((1?[0-9]):([0-5][0-9]))[ap]m,并且输入11:59am out:Match ((11):(59))am*/public static void testGroupMatch() {Scanner in = new Scanner(System.in);System.out.println("Enter pattern: ");String patternString = in.nextLine();
Pattern pattern = null;try {pattern = Patternpile(patternString);} catch (PatternSyntaxException e) {System.out.println("attern syntax error");System.exit(1);}
while (true) {System.out.println("Enter string to match: ");String input = in.nextLine();if (input == null || input.equals(""))return;Matcher matcher = pattern.matcher(input);if (matcher.matches()) {System.out.println("Match!");int g = matcher.groupCount();// 获得总的分组数if (g  0) {for (int i = 0; i  input.length(); i++) {for (int j = 1; j = g; j++) {// 第0个分组代表所有的分组,第一个实际分组的索引是1。if (i == matcher.start(j)) {// 此位置是分组的起始System.out.print('(');}}System.out.print(input.charAt(i));for (int j = 1; j = g; j++) {if (i + 1 == matcher.end(j)) {// 下一个位置是分组的完毕System.out.print(')');}}}System.out.println();}} elseSystem.out.println("No match");}}
3.Java代码 /** * This program displays all URLs in a web page by matching * a regular expression that describes the a href=... HTML tag. * @param urlString */ public static void testHrefMatch(String urlString) {  if (urlString == null || urlString == "") {  urlString = "java.sun";  }  try {  InputStreamReader in = new InputStreamReader(new URL(urlString)  .openStream());  StringBuilder input = new StringBuilder();  int ch;  while ((ch = in.read()) != -1) {  input.append((char) ch);  }  String patternString = "a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s])\\s*";  Pattern pattern = Patternpile(patternString,  Pattern.CASE_INSENSITIVE);  Matcher matcher = pattern.matcher(input);  while (matcher.find()) {  int start = matcher.start();  int end = matcher.end();  String match = input.substring(start, end);  System.out.println(match);  }   } catch (Exception e) {  e.printStackTrace();  } }
/** * This program displays all URLs in a web page by matching * a regular expression that describes the a href=... HTML tag.  * @param urlString */public static void testHrefMatch(String urlString) {if (urlString == null || urlString == "") {urlString = "java.sun";}try {InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());StringBuilder input = new StringBuilder();int ch;while ((ch = in.read()) != -1) {input.append((char) ch);}String patternString = "a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s])\\s*"attern pattern = Patternpile(patternString,Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(input);while (matcher.find()) {int start = matcher.start();int end = matcher.end();String match = input.substring(start, end);System.out.println(match);}
} catch (Exception e) {e.printStackTrace();}}
TAG:
Java
JAVA
java
regex
syntax文章由姿美堂整理,收集辛苦,希望能保留出处,谢谢斑竹大哥。




欢迎光临 编程开发论坛 (http://bbs.lihuasoft.net/) Powered by Discuz! 6.0.0