`
uule
  • 浏览: 6310834 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

[转]正则表达式总结

 
阅读更多

        由于项目中需要用到正则表达式,再一每次使用正则表达式时都要查资料,很是繁琐。于是乎,急需把平时积累的知识总结出来作为读书笔记。该篇文章包括了正则表达式的基本知识的介绍,并附加了四五个有代表性的例子,它们均用 java 和 javascript 来实现(最后一个例子是求 ip 地址的正则表达式,只使用 javascript 来做例子。我看很多网站给出的表达式都是不准确的,该例子我测试过,并列出了得出正确结果前我所写的错误的表达式,并给出错误的原因),以体现它们之间的区别。写这篇文章的同时还参考了以下的文章:
        http://edu.yesky.com/edupxpt/18/2143018.shtml
        http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm

        ● 句点符号
        句点符号符号匹配所有字符,包括空格、Tab字符甚至换行符。正则表达式 t.n 匹配 tan, ten, tin, ton, t#n, tpn, 甚至 t n,还有其它许多无意义的组合。

        ● 方括号符号
        为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号("[]")里面指定看来有意义的字符。此时,只有方括号里面指定的字符才参与匹配。也就是说,正则表达式 t[aeio]n 只匹配 tan, Ten, tin 和 ton。但 Toon 不匹配,因为在方括号之内你只能匹配单个字符。

        ● 或符号
        如果除了上面匹配的所有单词之外,你还想要匹配 toon,那么,你可以使用 "|" 操作符。"|" 操作符的基本意义就是"或"运算。要匹配 toon,使用 t(a|e|i|o|oo)n 正则表达式。这里不能使用方扩号,因为方括号只允许匹配单个字符。这里必须使用圆括号 "()" 。圆括号还可以用来分组,具体请参见后面介绍。

        ● 量词
        量词描述了一个模式吸收输入文本的方式:

  1. 贪婪的:量词总是贪婪的,除非有其它的选项被设置。贪婪表达式会为所有可能的模式发现尽可能多的匹配。导致此问题的一个典型理由就是假定我们的模式仅能匹配第一个可能的字符组,如果它确实是贪婪的,那么它就会继续往下匹配。
  2. 勉强的:用问号来指定,这个量词匹配满足模式所需的最少字符数。因此也称为懒惰的、最少匹配、非贪婪的或不贪婪的(lazy, minimal matching, non-greedy, or ungreedy)。
  3. 占有的:量词当前只有在 java 语言中才可用(在其它语言中不可用),并且它也更高级,因此我们大概不会立即用到它。当正则表达式被应用于字符串时,它会产生相当多的状态以便在匹配失败时可以回溯。而占有量词并不保存这些中间状态,因此它们可以防止回溯。它们常常用于防止正则表达式失控,因此可以使正则表达式执行起来更有效。
Greey Reluctant Possessive Matches
X? X?? X?+ X, 0 次或 1 次
X* X*? X*+ X, 0 次或多次
X+ X+? X++ X, 1 次或多次。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
X{n} X{n}? X{n}+ X, 恰好 n 次
X{n,} X{n,}? X{n,}+ X, 至少 n 次
X{n,m} X{n,m}? X{n,m}+ X, 至少 n 次,至多 m 次,即为闭集合,[n, m]


       假设要匹配类似这样的字符串:999-99-9999(连字符 "-"  在正则表达式中有特殊的含义,表示范围,因此在写正则表达式时需转义),我们可以使用如下图所示的正则表达式:

        假设你希望连字符号可以出现,也可以不出现——即,999-99-9999 和 999999999 都属于正确的格式。这时,你可以在连字符号后面加上 "?" 数量限定符号,我们可以使用如下图所示的正则表达式:

        下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分 "[0-9]{4}",再加上字母部分 "[A-Z]{2}"。我们可以使用如下图所示的正则表达式:


        ● "否" 符号(^)
        "^" 符号称为 "否" 符号。如果用在方括号内,"^" 表示不想要匹配的字符。例如,下图的正则表达式匹配所有单词,但以 "X" 字母开头的单词除外。


        ● 圆括号和空白符号
        假设要从格式为 "June 26, 1951" 的生日日期中提取出月份部分,用来匹配该日期的正则表达式可以如下图所示:

        新出现的 "\s" 符号是空白符号,匹配所有的空白字符,包括 Tab 字符。如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组,然后用 ORO API(本文后面详细讨论)提取出它的值。修改后的正则表达式如下图所示:


        ● 字符类

符号 描述
. 表示任何字符
[abc] 包含 a, b, c 的任何字符
[^abc] 除了 a, b, c 之外的任何字符(否定)
[a-zA-Z] 任何 a 到 z 或 A 到 Z 的任何字符(范围)
[abc[hij]] 任何 a, b, c, h, i, j 字符(合并)
[abc&&[hij]]                                                                          任何 h, i 或 j{交)
\s whitespace 符(空格[13], tab[\t], 换行[\r], 换页[\f], 回车[\n])                                  
\S 非 whitespace 符([^\s])
\d 数字 [0-9])
\D 非数字 [^0-9])
\w word character [a-zA-Z_0-9])
\W 非 word character [^\w])



        ● 边界匹配

符号                                                           描述                                                        
^ 一行的开始
$ 一行的结束
\b 词界
\B 非词界
\G 上一级结尾



        ● 模式标记

Compile Flag(for Java) Effect
Pattern.CANON_EQ 两个字符当且仅当它们的完全规范分解想匹配时,就认为它们是匹配的。例如,如果我们指定这个标记,表达式 "a\u030A" 就会匹配字符串 "?"。缺省情况下,匹配不考虑规范的等价性。
Pattern.CASE_INSENSITIVE(?i) 缺省情况下,大小写不敏感的匹配假定只有在 US-ASCII 字符集中的字符才能进行。这个标记允许我们的模式匹配不考虑大小写(大些或小写)。通过指定 UNICODE_CASE 标记并与此标记结合起来,基于 Unicode 大小写不敏感的匹配就可以使能。
Pattern.COMMENTS(?x) 在这种模式下,空格符将被忽略掉,并且以 # 开始直到行末的注释也会被忽略掉。通过嵌入的标记表达式也可以使能 Unix 的行模式。
Pattern.DOTALL(?s) 在 dotall 模式下,表达式 "." 匹配所有字符,包括行终结符。缺省情况下,"." 表达式不匹配行终结符。
Pattern.MULTILINE(?m) 在多行模式下,表达式 "^" 和 "$" 分别匹配一行的开始和结束。"^" 还匹配输入字符串的开始,而 "$" 也还匹配输入字符串的结尾。缺省情况下,这些表达式仅匹配输入的完整字符串的开始和结束。
Pattern.UNICODE_CASE(?u) 当指定这个标记,并且使能 CASE_INSENSITIVE 时,大小写不敏感的匹配将按照与 Unicode 标准相一致的方式进行。缺省情况下,大小写不敏感的匹配假定只能在 US-ASCII 字符集中的字符才能匹配。
Pattern.UNIX_LINE(?d) 在这种情况下,".", "^" 和 "$" 行为中,只识别行终结符 "\n"。

 

Compile Flag(for Javascript) Effect
i Perform case-insensitive matching.
g Perform a global matchthat is, find all matches rather than stopping after the first match.
m Multiline mode. ^ matches beginning of line or beginning of string, and $ matches end of line or end of string.



        ● 例子

Java代码  收藏代码
  1. /**  
  2.  * 此例子介绍 java 和 javascript 中有关正则表达式的基本 api  
  3.  */   
  4.   
  5. //~--------------------------------------- For Java -------------------------------------   
  6. // 通过 Pattern 类的静态方法 compile,传递一正则表达式字符串,构建一 Pattern 对象   
  7. Pattern p = Pattern.compile(String regex);  
  8. // 使用 Pattern 对象去匹配一个CharSequence对象(String,StringBuffer和CharBuffer对象实现了此接口)   
  9. Matcher m = p.matcher(CharSequence input);  
  10. /**  
  11.  * 接着可以使用 Matcher 对象访问结果,并利用一些方法来判断各种类型的匹配是成功或是失败:  
  12.  *     boolean matches();  
  13.  *     boolean lookingAt();  
  14.  *     boolean find();  
  15.  *     boolean find(int start);  
  16.  *  
  17.  * 如果模式匹配整个输入字符串,则 matches() 方法成功,否则失败。而且,如果输入字符串从一开始就是  
  18.  * 模式的一个匹配,那么 lookingAt() 方法也是成功的。lookingAt() 不需要匹配整个输入,只要从一开始  
  19.  * 能匹配即可,而 matches() 需要匹配整个输入。  
  20.  *  
  21.  * Pattern 对象还有一个静态方法:boolean matches(regex, input) 用于快速匹配(完全匹配)。  
  22.  * 这和 boolean str.matches(regex) 是等价的。  
  23.  *  
  24.  * 组是由圆括号分开的正则表达式,随后可以根据它们的组号进行调用。第 0 组表示整个匹配表达式,第 1 组  
  25.  * 表示第 1 个用圆括号括起来的组,等到。因此,在表达式 A(B(C))D 中,有三个组:第 0 组 ABCD,第 1 组  
  26.  * 是 BC 以及第 2 组 C。  
  27.  *  
  28.  * Matcher 对象有一些方法可以向我们提供有关组的信息:  
  29.  *   public int groupCount() 返回本匹配器的模式中分组的数目。第 0 组不包括在内  
  30.  *   pubilc String group() 返回前一次匹配操作(例如:find()) 的第 0 组(整个匹配)  
  31.  *   public String group(int i) 返回在前一次匹配操作期间指定的组。如果匹配成功,但是指定的组没有  
  32.  *                              匹配输入字符串的任何部分,则返回 null  
  33.  *  
  34.  * find() 常用方式是:  
  35.  *   while (m.find()) {  
  36.  *     System.out.println(m.group());  
  37.  *   }  
  38.  *  
  39.  *   while (m.find()) {  
  40.  *     for (int j = 0; j < m.groupCount(); j++) {  
  41.  *       System.out.println(m.group[j]);  
  42.  *     }  
  43.  *     System.out.println();  
  44.  *   }  
  45.  */   
  46.   
  47. //~------------------------------------- For Javascript ---------------------------------   
  48. /**  
  49.  * In JavaScript, regular expressions are represented by RegExp objects. RegExp objects  
  50.  * may be created with the RegExp( ) constructor, of course, but they are more often  
  51.  * created using a special literal syntax. Just as string literals are specified as  
  52.  * characters within quotation marks, regular expression literals are specified as  
  53.  * characters within a pair of slash (/) characters. Thus, your JavaScript code may  
  54.  * contain lines like this:  
  55.  *  
  56.  * var pattern = /s$/;  
  57.  *  
  58.  * This line creates a new RegExp object and assigns it to the variable pattern. This  
  59.  * particular RegExp object matches any string that ends with the letter "s." (I'll get  
  60.  * into the grammar for defining patterns shortly.) This regular expression could have  
  61.  * equivalently been defined with the RegExp( ) constructor like this:  
  62.  *  
  63.  * var pattern = new RegExp("s$");  
  64.  *  
  65.  * Strings support four methods that use regular expressions. They are search(),  
  66.  * replace(), match() and split().  
  67.  *  
  68.  * The simplest is search( ). Function signature as follows:  
  69.  *   int search(Regex regex)  
  70.  *   int search(String literal)  
  71.  * This method takes a regular expression argument and returns either the character  
  72.  * position of the start of the first matching substring or -1 if there is no match.  
  73.  * For example, the following call returns 4: "JavaScript".search(/script/i);  
  74.  *  
  75.  * If the argument to search( ) is not a regular expression, it is first converted to one  
  76.  * by passing it to the RegExp constructor. search( ) does not support global searches; it  
  77.  * ignores the g flag of its regular expression argument.  
  78.  *  
  79.  * Then is the replace( ) method. Function signature as follows:  
  80.  *   String replace(Regex regex, String replacement)  
  81.  *   String replace(String literal, String replacement)  
  82.  * The replace( ) method performs a search-and-replace operation. It takes a regular  
  83.  * expression as its first argument and a replacement string as its second argument. It  
  84.  * searches the string on which it is called for matches with the specified pattern. If  
  85.  * the regular expression has the g flag set, the replace( ) method replaces all matches  
  86.  * in the string with the replacement string; otherwise, it replaces only the first match  
  87.  * it finds. If the first argument to replace( ) is a string rather than a regular  
  88.  * expression, the method searches for that string literally rather than converting it to  
  89.  * a regular expression with the RegExp( ) constructor, as search( ) does.  
  90.  *  
  91.  * Next is the match( ) method. Function signature as follows:  
  92.  *   Array<String> match(Regex regex)  
  93.  * The match( ) method is the most general of the String regular-expression methods. It  
  94.  * takes a regular expression as its only argument (or converts its argument to a regular  
  95.  * expression by passing it to the RegExp( ) constructor) and returns an array that  
  96.  * contains the results of the match. If the regular expression has the g flag set, the  
  97.  * method returns an array of all matches that appear in the string. For example:  
  98.  *  
  99.  * "1 plus 2 equals 3".match(/java/)  // returns null  
  100.  * "1 plus 2 equals 3".match(/\d+/)   // returns ["1"]  
  101.  * "1 plus 2 equals 3".match(/\d+/g)  // returns ["1", "2", "3"]  
  102.  *  
  103.  * Finally, you should know about one more feature of the match( ) method. The array it  
  104.  * returns has a length property, as all arrays do. When match( ) is invoked on a nonglo-  
  105.  * bal regular expression, however, the returned array also has two other properties: the  
  106.  * index property, which contains the character position within the string at which the  
  107.  * match begins, and the input property, which is a copy of the target string.  For a  
  108.  * regular expression r and string s that does not have the g flag set, calling s.match(r)  
  109.  * returns the same value as r.exec(s). The RegExp.exec( ) method is discussed a little  
  110.  * later.  
  111.  *  
  112.  * The last of the regular-expression methods of the String object is split( ).  
  113.  *  
  114.  * The RegExp Object:  
  115.  * Regular expressions are represented as RegExp objects. In addition to the RegExp( )  
  116.  * constructor, RegExp objects support three methods and a number of properties. An unus-  
  117.  * ual feature of the RegExp class is that it defines both class (or static) properties  
  118.  * and instance properties. That is, it defines global properties that belong to the  
  119.  * RegExp( ) constructor as well as other properties that belong to individual RegExp  
  120.  * objects. The RegExp( ) constructor takes one or two string arguments and creates a new  
  121.  * RegExp object. The first argument to this constructor is a string that contains the  
  122.  * body of the regular expressionthe text that would appear within slashes in a regular  
  123.  * expression literal. Note that both string literals and regular expressions use the \  
  124.  * character for escape sequences, so when you pass a regular expression to RegExp( ) as a  
  125.  * string literal, you must replace each \ character with \\. The second argument to  
  126.  * RegExp( ) is optional. If supplied, it indicates the regular expression flags. It  
  127.  * should be g, i, m, or a combination of those letters. For example:  
  128.  *  
  129.  * // Find all five-digit numbers in a string. Note the double \\ in this case.  
  130.  * var zipcode = new RegExp("\\d{5}", "g");  
  131.  *  
  132.  * RegExp Methods for Pattern Matching:  
  133.  * RegExp objects define two methods[exec( ) and test( )] that perform pattern matching  
  134.  * operations; they behave similarly to the String methods described earlier. The main  
  135.  * RegExp pattern matching method is exec( ). It is similar to the String match( ) method  
  136.  * except that it is a RegExp method that takes a string, rather than a String method that  
  137.  * takes a RegExp. The exec( ) method executes a regular expression on the specified  
  138.  * string. That is, it searches the string for a match. If it finds none, it returns null.  
  139.  * If it does find one, however, it returns an array just like the array returned by the  
  140.  * match( ) method for nonglobal searches. Element 0 of the array contains the string that  
  141.  * matched the regular expression, and any subsequent array elements contain the substrings  
  142.  * that matched any parenthesized subexpressions. Furthermore, the index property contains  
  143.  * the character position at which he match occurred, and the input property refers to the  
  144.  * string that was searched.  
  145.  *  
  146.  * Unlike the match( ) method, exec( ) returns the same kind of array whether or not the  
  147.  * regular expression has the global g flag. Recall that match( ) returns an array of  
  148.  * matches when passed a global regular expression. exec( ), by contrast, always returns  
  149.  * a single match and provides complete information about that match. When exec( ) is  
  150.  * called on a regular expression that has the g flag, it sets the lastIndex property of  
  151.  * the regular expression object to the character position immediately following the  
  152.  * matched substring. If exec( ) is called on a regular expression that doesn't have g  
  153.  * flag, it wouldn't change the lastIndex property, so when use while( ) to loop, you  
  154.  * would get a dead loop when it could match the input(can't match wouldn't lead dead lo-  
  155.  * op, for the loop condition is false). When exec( ) is invoked a second time for the  
  156.  * same regular expression, it begins its search at the character position indicated by  
  157.  * the lastIndex property. If exec( ) does not find a match, it resets lastIndex to 0.  
  158.  * (You can also set lastIndex to 0 at any time, which you should do whenever you quit a  
  159.  * search before you find the last match in one string and begin searching another string  
  160.  * with the same RegExp object.) This special behavior allows you to call exec( ) repeate-  
  161.  * dly in order to loop through all the regular expression matches in a string.  
  162.  * For example:  
  163.  *  
  164.  * Regex Object's function signature as  
  165.  * Array exec(String) (with g flag or not, it return array of size 1 unless it mathes none)  
  166.  * boolean test(String) (it returns true if mathes, otherwise false)  
  167.  *  
  168.  * var content = "JavaScript is more fun than Java!";  
  169.  * var p1 = /java/i;  
  170.  * var p2 = /java/ig;  
  171.  * var p3 = /javaX/i;  
  172.  
  173.  * p1.exec(content);        // ["Java"], it doesn't change pattern's lastIndex property.  
  174.  * p2.exec(content);        // ["Java"] not ["Java", "Java"], it changes pattern's  
  175.  *                          // lastIndex property for pattern with "g" flag  
  176.  * p3.exec(content);        // null  
  177.  *  
  178.  * var pattern = /Java/g;  
  179.  * var text = "JavaScript is more fun than Java!";  
  180.  * var result;  
  181.  * while ((result = pattern.exec(text)) != null) {  
  182.  *   alert("Matched '" + result[0] + "'" +  
  183.  *        " at position " + result.index +  
  184.  *        "; next search begins at " + pattern.lastIndex);  
  185.  * }  
  186.  *  
  187.  * The other RegExp method is test( ). test( ) is a much simpler method than exec( ). It  
  188.  * takes a string and returns true if the string contains a match for the regular  
  189.  * expression:  
  190.  *  
  191.  * var pattern = /java/i;       // As long as the matched string occurs "java" ignoring  
  192.  * pattern.test("JavaScript");  // case, which would return true for it is not the whole  
  193.  *                              // match. If we need the whole match effect, we should  
  194.  *                              // alter the pattern with prefix "^" and suffix "$".  
  195.  *  
  196.  * var pattern = /^java$/i;     // The String must be "java" ignoring case and the matched  
  197.  * pattern.test("JavaScript");  // string can't occur any other characters, which will  
  198.                                 // return false for it is the whole match just as  
  199.  *                              // java.util.regex.Pattern.matches().  
  200.  *  
  201.  * (/^java$/i).test("Javascript") is also legal javascript expression.  
  202.  *  
  203.  * var strRegex = "/java/i";  
  204.  * (eval(strRegex)).test("hello java!"); // return true, it is legal javascript expression.  
  205.  *  
  206.  * Calling test( ) is equivalent to calling exec( ) and returning TRUE if the return value  
  207.  * of exec( ) is not null. Because of this equivalence, the test( ) method behaves the  
  208.  * same way as the exec( ) method when invoked for a global regular expression: it begins  
  209.  * searching the specified string at the position specified by lastIndex, and if it finds  
  210.  * a match, it sets lastIndex to the position of the character immediately following the  
  211.  * match. Thus, you can loop through a string using the test( ) method just as you can  
  212.  * with the exec( ) method.  
  213.  *  
  214.  * RegExp Instance Properties:  
  215.  * Each RegExp object has five properties. The source property is a read-only string that  
  216.  * contains the text of the regular expression. The global property is a read-only boolean  
  217.  * value that specifies whether the regular expression has the g flag. The ignoreCase  
  218.  * property is a read-only boolean value that specifies whether the regular expression has  
  219.  * the i flag. The multiline property is a read-only boolean value that specifies whether  
  220.  * the regular expression has the m flag. The final property is lastIndex, a read/write  
  221.  * integer. For patterns with the g flag, this property stores the position in the string  
  222.  * at which the next search is to begin. It is used by the exec( ) and test( ) methods.  
  223.  */   
/**
 * 此例子介绍 java 和 javascript 中有关正则表达式的基本 api
 */

//~--------------------------------------- For Java -------------------------------------
// 通过 Pattern 类的静态方法 compile,传递一正则表达式字符串,构建一 Pattern 对象
Pattern p = Pattern.compile(String regex);
// 使用 Pattern 对象去匹配一个CharSequence对象(String,StringBuffer和CharBuffer对象实现了此接口)
Matcher m = p.matcher(CharSequence input);
/**
 * 接着可以使用 Matcher 对象访问结果,并利用一些方法来判断各种类型的匹配是成功或是失败:
 *     boolean matches();
 *     boolean lookingAt();
 *     boolean find();
 *     boolean find(int start);
 *
 * 如果模式匹配整个输入字符串,则 matches() 方法成功,否则失败。而且,如果输入字符串从一开始就是
 * 模式的一个匹配,那么 lookingAt() 方法也是成功的。lookingAt() 不需要匹配整个输入,只要从一开始
 * 能匹配即可,而 matches() 需要匹配整个输入。
 *
 * Pattern 对象还有一个静态方法:boolean matches(regex, input) 用于快速匹配(完全匹配)。
 * 这和 boolean str.matches(regex) 是等价的。
 *
 * 组是由圆括号分开的正则表达式,随后可以根据它们的组号进行调用。第 0 组表示整个匹配表达式,第 1 组
 * 表示第 1 个用圆括号括起来的组,等到。因此,在表达式 A(B(C))D 中,有三个组:第 0 组 ABCD,第 1 组
 * 是 BC 以及第 2 组 C。
 *
 * Matcher 对象有一些方法可以向我们提供有关组的信息:
 *   public int groupCount() 返回本匹配器的模式中分组的数目。第 0 组不包括在内
 *   pubilc String group() 返回前一次匹配操作(例如:find()) 的第 0 组(整个匹配)
 *   public String group(int i) 返回在前一次匹配操作期间指定的组。如果匹配成功,但是指定的组没有
 *                              匹配输入字符串的任何部分,则返回 null
 *
 * find() 常用方式是:
 *   while (m.find()) {
 *     System.out.println(m.group());
 *   }
 *
 *   while (m.find()) {
 *     for (int j = 0; j < m.groupCount(); j++) {
 *       System.out.println(m.group[j]);
 *     }
 *     System.out.println();
 *   }
 */

//~------------------------------------- For Javascript ---------------------------------
/**
 * In JavaScript, regular expressions are represented by RegExp objects. RegExp objects
 * may be created with the RegExp( ) constructor, of course, but they are more often
 * created using a special literal syntax. Just as string literals are specified as
 * characters within quotation marks, regular expression literals are specified as
 * characters within a pair of slash (/) characters. Thus, your JavaScript code may
 * contain lines like this:
 *
 * var pattern = /s$/;
 *
 * This line creates a new RegExp object and assigns it to the variable pattern. This
 * particular RegExp object matches any string that ends with the letter "s." (I'll get
 * into the grammar for defining patterns shortly.) This regular expression could have
 * equivalently been defined with the RegExp( ) constructor like this:
 *
 * var pattern = new RegExp("s$");
 *
 * Strings support four methods that use regular expressions. They are search(),
 * replace(), match() and split().
 *
 * The simplest is search( ). Function signature as follows:
 *   int search(Regex regex)
 *   int search(String literal)
 * This method takes a regular expression argument and returns either the character
 * position of the start of the first matching substring or -1 if there is no match.
 * For example, the following call returns 4: "JavaScript".search(/script/i);
 *
 * If the argument to search( ) is not a regular expression, it is first converted to one
 * by passing it to the RegExp constructor. search( ) does not support global searches; it
 * ignores the g flag of its regular expression argument.
 *
 * Then is the replace( ) method. Function signature as follows:
 *   String replace(Regex regex, String replacement)
 *   String replace(String literal, String replacement)
 * The replace( ) method performs a search-and-replace operation. It takes a regular
 * expression as its first argument and a replacement string as its second argument. It
 * searches the string on which it is called for matches with the specified pattern. If
 * the regular expression has the g flag set, the replace( ) method replaces all matches
 * in the string with the replacement string; otherwise, it replaces only the first match
 * it finds. If the first argument to replace( ) is a string rather than a regular
 * expression, the method searches for that string literally rather than converting it to
 * a regular expression with the RegExp( ) constructor, as search( ) does.
 *
 * Next is the match( ) method. Function signature as follows:
 *   Array<String> match(Regex regex)
 * The match( ) method is the most general of the String regular-expression methods. It
 * takes a regular expression as its only argument (or converts its argument to a regular
 * expression by passing it to the RegExp( ) constructor) and returns an array that
 * contains the results of the match. If the regular expression has the g flag set, the
 * method returns an array of all matches that appear in the string. For example:
 *
 * "1 plus 2 equals 3".match(/java/)  // returns null
 * "1 plus 2 equals 3".match(/\d+/)   // returns ["1"]
 * "1 plus 2 equals 3".match(/\d+/g)  // returns ["1", "2", "3"]
 *
 * Finally, you should know about one more feature of the match( ) method. The array it
 * returns has a length property, as all arrays do. When match( ) is invoked on a nonglo-
 * bal regular expression, however, the returned array also has two other properties: the
 * index property, which contains the character position within the string at which the
 * match begins, and the input property, which is a copy of the target string.  For a
 * regular expression r and string s that does not have the g flag set, calling s.match(r)
 * returns the same value as r.exec(s). The RegExp.exec( ) method is discussed a little
 * later.
 *
 * The last of the regular-expression methods of the String object is split( ).
 *
 * The RegExp Object:
 * Regular expressions are represented as RegExp objects. In addition to the RegExp( )
 * constructor, RegExp objects support three methods and a number of properties. An unus-
 * ual feature of the RegExp class is that it defines both class (or static) properties
 * and instance properties. That is, it defines global properties that belong to the
 * RegExp( ) constructor as well as other properties that belong to individual RegExp
 * objects. The RegExp( ) constructor takes one or two string arguments and creates a new
 * RegExp object. The first argument to this constructor is a string that contains the
 * body of the regular expressionthe text that would appear within slashes in a regular
 * expression literal. Note that both string literals and regular expressions use the \
 * character for escape sequences, so when you pass a regular expression to RegExp( ) as a
 * string literal, you must replace each \ character with \\. The second argument to
 * RegExp( ) is optional. If supplied, it indicates the regular expression flags. It
 * should be g, i, m, or a combination of those letters. For example:
 *
 * // Find all five-digit numbers in a string. Note the double \\ in this case.
 * var zipcode = new RegExp("\\d{5}", "g");
 *
 * RegExp Methods for Pattern Matching:
 * RegExp objects define two methods[exec( ) and test( )] that perform pattern matching
 * operations; they behave similarly to the String methods described earlier. The main
 * RegExp pattern matching method is exec( ). It is similar to the String match( ) method
 * except that it is a RegExp method that takes a string, rather than a String method that
 * takes a RegExp. The exec( ) method executes a regular expression on the specified
 * string. That is, it searches the string for a match. If it finds none, it returns null.
 * If it does find one, however, it returns an array just like the array returned by the
 * match( ) method for nonglobal searches. Element 0 of the array contains the string that
 * matched the regular expression, and any subsequent array elements contain the substrings
 * that matched any parenthesized subexpressions. Furthermore, the index property contains
 * the character position at which he match occurred, and the input property refers to the
 * string that was searched.
 *
 * Unlike the match( ) method, exec( ) returns the same kind of array whether or not the
 * regular expression has the global g flag. Recall that match( ) returns an array of
 * matches when passed a global regular expression. exec( ), by contrast, always returns
 * a single match and provides complete information about that match. When exec( ) is
 * called on a regular expression that has the g flag, it sets the lastIndex property of
 * the regular expression object to the character position immediately following the
 * matched substring. If exec( ) is called on a regular expression that doesn't have g
 * flag, it wouldn't change the lastIndex property, so when use while( ) to loop, you
 * would get a dead loop when it could match the input(can't match wouldn't lead dead lo-
 * op, for the loop condition is false). When exec( ) is invoked a second time for the
 * same regular expression, it begins its search at the character position indicated by
 * the lastIndex property. If exec( ) does not find a match, it resets lastIndex to 0.
 * (You can also set lastIndex to 0 at any time, which you should do whenever you quit a
 * search before you find the last match in one string and begin searching another string
 * with the same RegExp object.) This special behavior allows you to call exec( ) repeate-
 * dly in order to loop through all the regular expression matches in a string.
 * For example:
 *
 * Regex Object's function signature as
 * Array exec(String) (with g flag or not, it return array of size 1 unless it mathes none)
 * boolean test(String) (it returns true if mathes, otherwise false)
 *
 * var content = "JavaScript is more fun than Java!";
 * var p1 = /java/i;
 * var p2 = /java/ig;
 * var p3 = /javaX/i;

 * p1.exec(content);        // ["Java"], it doesn't change pattern's lastIndex property.
 * p2.exec(content);        // ["Java"] not ["Java", "Java"], it changes pattern's
 *                          // lastIndex property for pattern with "g" flag
 * p3.exec(content);        // null
 *
 * var pattern = /Java/g;
 * var text = "JavaScript is more fun than Java!";
 * var result;
 * while ((result = pattern.exec(text)) != null) {
 *   alert("Matched '" + result[0] + "'" +
 *        " at position " + result.index +
 *        "; next search begins at " + pattern.lastIndex);
 * }
 *
 * The other RegExp method is test( ). test( ) is a much simpler method than exec( ). It
 * takes a string and returns true if the string contains a match for the regular
 * expression:
 *
 * var pattern = /java/i;       // As long as the matched string occurs "java" ignoring
 * pattern.test("JavaScript");  // case, which would return true for it is not the whole
 *                              // match. If we need the whole match effect, we should
 *                              // alter the pattern with prefix "^" and suffix "$".
 *
 * var pattern = /^java$/i;     // The String must be "java" ignoring case and the matched
 * pattern.test("JavaScript");  // string can't occur any other characters, which will
                                // return false for it is the whole match just as
 *                              // java.util.regex.Pattern.matches().
 *
 * (/^java$/i).test("Javascript") is also legal javascript expression.
 *
 * var strRegex = "/java/i";
 * (eval(strRegex)).test("hello java!"); // return true, it is legal javascript expression.
 *
 * Calling test( ) is equivalent to calling exec( ) and returning TRUE if the return value
 * of exec( ) is not null. Because of this equivalence, the test( ) method behaves the
 * same way as the exec( ) method when invoked for a global regular expression: it begins
 * searching the specified string at the position specified by lastIndex, and if it finds
 * a match, it sets lastIndex to the position of the character immediately following the
 * match. Thus, you can loop through a string using the test( ) method just as you can
 * with the exec( ) method.
 *
 * RegExp Instance Properties:
 * Each RegExp object has five properties. The source property is a read-only string that
 * contains the text of the regular expression. The global property is a read-only boolean
 * value that specifies whether the regular expression has the g flag. The ignoreCase
 * property is a read-only boolean value that specifies whether the regular expression has
 * the i flag. The multiline property is a read-only boolean value that specifies whether
 * the regular expression has the m flag. The final property is lastIndex, a read/write
 * integer. For patterns with the g flag, this property stores the position in the string
 * at which the next search is to begin. It is used by the exec( ) and test( ) methods.
 */

 

Java代码  收藏代码
  1. /**  
  2.  * 使用 java 和 javascript 演示模式匹配。  
  3.  * 这里使用多行和不区分大小的模式来演示,因为 java 和 javascript 中均有此模式。  
  4.  */   
  5.   
  6. //~--------------------------------------- For Java -------------------------------------   
  7. // 1. Use pattern in literal regular expression(?mi)   
  8. Pattern pattern = Pattern.compile("(?mi)JAVA\\w*" );  
  9. String input = "java has regex\nJava has regex\n"  +  
  10.   "JAVA has pretty good regular expressions\n"  +  
  11.   "Regular expressions are in Java" ;  
  12. // true   
  13. System.out.println(pattern.matcher(input).find());  
  14.   
  15. // 2. Use Pattern.complile()'s reload method, use OR(|) operator to realize multi patterns   
  16. Pattern pattern = Pattern.compile("JAVA\\w*" , Pattern.MULTILINE|Pattern.CASE_INSENSITIVE);  
  17. String s = "java has regex\nJava has regex\n"  +  
  18.   "JAVA has pretty good regular expressions\n"  +  
  19.   "Regular expressions are in Java" ;  
  20. // true   
  21. System.out.println(pattern.matcher(s).find());  
  22.   
  23. //~------------------------------------- For Javascript ---------------------------------   
  24. // 1. Use pattern in literal regular expression(?mi)   
  25. var pattern = /JAVA/mi;  
  26. var input = "java has regex\nJava has regex\n"  +  
  27.   "JAVA has pretty good regular expressions\n"  +  
  28.   "Regular expressions are in Java" ;  
  29. // true   
  30. alert(pattern.test(input));  
  31.   
  32. // 2. Use Regex object's two-argument constructor. It should be g, i, m, or a   
  33. // combination of those letters   
  34. /**  
  35.  * If exec( ) is called on a regular expression that doesn't have g flag, it wouldn't  
  36.  * change the lastIndex property, so when use while( ) to loop, you would get a dead loop  
  37.  * when it could match the input(can't match wouldn't lead dead loop, for the loop  
  38.  * condition is false).  
  39.  */   
  40. var pattern = new  RegExp( "JAVA" "gmi" );  
  41. var input = "java has regex\nJava has regex\n"  +  
  42.   "JAVA has pretty good regular expressions\n"  +  
  43.   "Regular expressions are in Java" ;  
  44. // true   
  45. alert(pattern.test(input));  
/**
 * 使用 java 和 javascript 演示模式匹配。
 * 这里使用多行和不区分大小的模式来演示,因为 java 和 javascript 中均有此模式。
 */

//~--------------------------------------- For Java -------------------------------------
// 1. Use pattern in literal regular expression(?mi)
Pattern pattern = Pattern.compile("(?mi)JAVA\\w*");
String input = "java has regex\nJava has regex\n" +
  "JAVA has pretty good regular expressions\n" +
  "Regular expressions are in Java";
// true
System.out.println(pattern.matcher(input).find());

// 2. Use Pattern.complile()'s reload method, use OR(|) operator to realize multi patterns
Pattern pattern = Pattern.compile("JAVA\\w*", Pattern.MULTILINE|Pattern.CASE_INSENSITIVE);
String s = "java has regex\nJava has regex\n" +
  "JAVA has pretty good regular expressions\n" +
  "Regular expressions are in Java";
// true
System.out.println(pattern.matcher(s).find());

//~------------------------------------- For Javascript ---------------------------------
// 1. Use pattern in literal regular expression(?mi)
var pattern = /JAVA/mi;
var input = "java has regex\nJava has regex\n" +
  "JAVA has pretty good regular expressions\n" +
  "Regular expressions are in Java";
// true
alert(pattern.test(input));

// 2. Use Regex object's two-argument constructor. It should be g, i, m, or a
// combination of those letters
/**
 * If exec( ) is called on a regular expression that doesn't have g flag, it wouldn't
 * change the lastIndex property, so when use while( ) to loop, you would get a dead loop
 * when it could match the input(can't match wouldn't lead dead loop, for the loop
 * condition is false).
 */
var pattern = new RegExp("JAVA", "gmi");
var input = "java has regex\nJava has regex\n" +
  "JAVA has pretty good regular expressions\n" +
  "Regular expressions are in Java";
// true
alert(pattern.test(input));

 

Java代码  收藏代码
  1. /**  
  2.  * 分组替换  
  3.  * 将字符串 "Aliy: 1983-09-21; Blaine: 2000-02-28; Tony: 1976-11-08"  
  4.  * 提取出每个人生日的月份,并将月份替换成中文的月份  
  5.  */   
  6.   
  7. //~--------------------------------------- For Java -------------------------------------   
  8. /**  
  9.  * Matcher 对象有一些替换操作,对于我们能方便的处理文本的替换。  
  10.  *   replaceFirst(String replacement): 用 replacement 替换输入字符串中最先匹配的那部分  
  11.  *   replaceAll(String replacement): 用 replacement 替换输入字符串中所有的匹配部分  
  12.  *   appendReplacement(StringBuffer sbuf, String replacement): 逐步地在 subf 中执行替换,而不  
  13.  *       是像 replaceFirst() 那样仅替换第一个匹配或者像 replaceAll() 是替换所有的匹配。这是个  
  14.  *       非常重要的方法,因为它允许我们通过调用某些方法并执行一些其它处理来产生 replacement(而  
  15.  *       replaceFirst() 和 replaceAll() 只能输入固定字符串)。有了这个方法,我们就可以通过编程来  
  16.  *       实现将目标拆分成组以及创建功能强大的替换。  
  17.  *  appendTail(StringBuffer subf): 在一个或多个 appendReplacement() 调用之后被调用,以便复制输  
  18.  *       入字符串的剩余部分。  
  19.  *  
  20.  * replaceFirst() 和 replaceAll() 中的替换字符串仅是字面意义上的,如果我们想在每个替换上执行一些  
  21.  * 操作,它们就不会太有帮助(replaceFirst 和 replaceAll() 在得到 Matcher 对象后可直接被调用,因此  
  22.  * 它如果要处理分组情况时就无能为力(得到 Matcher 对象后调用,此时拿不到分组信息)。当然,这两个方  
  23.  * 法可以在 while(Matcher.find()) 的循环中调用,循环中是可以得到分组信息的)。如果确实要那样的话,  
  24.  * 我们需要使用 appendReplacement(),它可以让我们将任意数量的代码编写进执行替换的过程。通常地,  
  25.  * 我们会逐步地执行所有替换,然后调用 appendTail(),但是如果我们想模仿 replaceFirst()(或者 "替换  
  26.  * 第 n 个"),我们仅需要执行一次替换,然后调用 appendTail() 把剩余部分输入到 subf 中即可。  
  27.  * 在 while(Matcher.find()) 中,我们可以通过 "$g"(其中 "g" 是组号)的形式,来在替代字符串中直接引用  
  28.  * 被捕获的组。  
  29.  */   
  30. String[] months = new  String[] {  
  31.     "一月" "二月" "三月" "四月" "五月" "六月" "七月" "八月" ,  
  32.     "九月" "十月" "十一月" "十二月"   
  33. };  
  34. Pattern pattern = Pattern.compile("(\\w+)(\\s*:\\s*\\d{4}-)(\\d{2})(-\\d{2})" );  
  35. String input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:"  +  
  36.     " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。" ;  
  37. String result = null ;  
  38. StringBuffer resultBuffer = new  StringBuffer();  
  39. Matcher matcher = pattern.matcher(input);  
  40. // matcher.replaceFirst 和 matcher.replaceAll() 可以在此调用,但它们拿不到分组信息,除非将此方法   
  41. // 的调用写入 while() 循环中   
  42. while  (matcher.find()) {  
  43.   // 在循环中可以得到分组信息   
  44.   String name = matcher.group(1 );  
  45.   String other1 = matcher.group(2 );  
  46.   String month = matcher.group(3 );  
  47.   String other2 = matcher.group(4 );  
  48.   matcher.appendReplacement(resultBuffer, "$1$2"  +  
  49.     months[Integer.parseInt(month)] + "$4" );  
  50. }  
  51. // 把剩余部分输入到 resultBuffer 中   
  52. matcher.appendTail(resultBuffer);  
  53. // 结果:以下是各个人员的出生日期信息:Aliy: 1983-十月-21; Blaine: 2000-三月-28; Tony:   
  54. // 1976-十二月-08; Joson: 1998-八月-08; Kite: 2001-十一月-20; Sanfansicico: 1991-四月-31。   
  55. System.out.println(resultBuffer);  
  56.   
  57. //~------------------------------------- For Javascript ---------------------------------   
  58. <script type="text/javascript"  language= "javascript" >  
  59.     var months = [  
  60.     "一月" "二月" "三月" "四月" "五月" "六月" "七月" "八月" ,  
  61.     "九月" "十月" "十一月" "十二月"  ];  
  62.   
  63.     var pattern = /(\w+\s*:\s*\d{4 }-)(\d{ 2 })(-\d{ 2 })/g;  
  64.     var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:"  +  
  65.     " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。" ;  
  66.   /**  
  67.    * 分成 3 组,$1 是第 1 组所代表的值,要用引号起来,$3 是第 3 组所代表的值,$2 是第 2 组所代表  
  68.    * 的值,也就是月份,但 months["$2"] 会让 js 引擎去找 months 的 $2 的属性,因此我们对月份无能  
  69.    * 为力了。如果不为分组信息做特殊处理,我们可以使用 String.replace(Regex, String) 来处理。  
  70.    */   
  71.     var result = input.replace(pattern, "$1"  + months[ "$2" ] +  "$3" );  
  72. </script>  
  73.   
  74. // 将 replace 函数的第二个参数使用 Function 对象   
  75. <script type="text/javascript"  language= "javascript" >  
  76.     /**  
  77.      * replace 把若干个参数传入此函数中:  
  78.      * 0: 依据正则表达式和源串得到的匹配的字符串,如:Aliy: 1983-09-21  
  79.      * 1: 正则表达式匹配到的字符串的第 1 个分组值,如:Aliy: 1983-  
  80.      * 2: 正则表达式匹配到的字符串的第 2 个分组值,如:Aliy: 09  
  81.      * 3: 正则表达式匹配到的字符串的第 3 个分组值,如:-21  
  82.      * ...  
  83.      * n: 正则表达式匹配到的字符串的第 n 个分组值  
  84.      * n + 1: 被匹配到的字符串在源串中的索引  
  85.      * n + 2: 源串,如:以下是各个人员的出生日期信息:Aliy: 1983-09-21; Bla ...(省略)  
  86.      */   
  87.     function replaceAction() {  
  88.         for  (var i =  0 ; i < arguments.length; i++) {  
  89.             alert("第 "  + i +  " 个参数的值为: "  + arguments[i]);  
  90.         }  
  91.   
  92.         // 这里可以对匹配的字符串为所欲为了   
  93.         // 这里直接返回匹配到的字符串,即不做任何替换   
  94.         return  arguments[ 0 ];  
  95.     };  
  96.   
  97.     var months = [  
  98.     "一月" "二月" "三月" "四月" "五月" "六月" "七月" "八月" ,  
  99.     "九月" "十月" "十一月" "十二月"  ];  
  100.   
  101.     var pattern = /(\w+\s*:\s*\d{4 }-)(\d{ 2 })(-\d{ 2 })/g;  
  102.     var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:"  +  
  103.     " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。" ;  
  104.   // js 引擎会将一些参数传入到 replaceAction 函数中,匹配 pattern 的串将被替换成 replaceAction   
  105.   // 函数的返回值。详见 replaceAction 说明   
  106.     var result = input.replace(pattern, replaceAction);  
  107. </script>  
  108.   
  109. // 完整的代码   
  110. <script type="text/javascript"  language= "javascript" >  
  111.     function replaceAction() {  
  112.         return  arguments[ 1 ] + months[parseInt(arguments[ 2 ])] + arguments[ 3 ];  
  113.     };  
  114.   
  115.     var months = [  
  116.     "一月" "二月" "三月" "四月" "五月" "六月" "七月" "八月" ,  
  117.     "九月" "十月" "十一月" "十二月"  ];  
  118.   
  119.     var pattern = /(\w+\s*:\s*\d{4 }-)(\d{ 2 })(-\d{ 2 })/g;  
  120.     var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:"  +  
  121.     " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。" ;  
  122.     var result = input.replace(pattern, replaceAction);  
  123.   // 结果:以下是各个人员的出生日期信息:Aliy: 1983-十月-21; Blaine: 2000-三月-28; Tony: 1976   
  124.   // -十二月-08; Joson: 1998-八月-08; Kite: 2001-十一月-20; Sanfansicico: 1991-四月-31。   
  125.     document.write(result);  
  126. </script>  
/**
 * 分组替换
 * 将字符串 "Aliy: 1983-09-21; Blaine: 2000-02-28; Tony: 1976-11-08"
 * 提取出每个人生日的月份,并将月份替换成中文的月份
 */

//~--------------------------------------- For Java -------------------------------------
/**
 * Matcher 对象有一些替换操作,对于我们能方便的处理文本的替换。
 *   replaceFirst(String replacement): 用 replacement 替换输入字符串中最先匹配的那部分
 *   replaceAll(String replacement): 用 replacement 替换输入字符串中所有的匹配部分
 *   appendReplacement(StringBuffer sbuf, String replacement): 逐步地在 subf 中执行替换,而不
 *       是像 replaceFirst() 那样仅替换第一个匹配或者像 replaceAll() 是替换所有的匹配。这是个
 *       非常重要的方法,因为它允许我们通过调用某些方法并执行一些其它处理来产生 replacement(而
 *       replaceFirst() 和 replaceAll() 只能输入固定字符串)。有了这个方法,我们就可以通过编程来
 *       实现将目标拆分成组以及创建功能强大的替换。
 *  appendTail(StringBuffer subf): 在一个或多个 appendReplacement() 调用之后被调用,以便复制输
 *       入字符串的剩余部分。
 *
 * replaceFirst() 和 replaceAll() 中的替换字符串仅是字面意义上的,如果我们想在每个替换上执行一些
 * 操作,它们就不会太有帮助(replaceFirst 和 replaceAll() 在得到 Matcher 对象后可直接被调用,因此
 * 它如果要处理分组情况时就无能为力(得到 Matcher 对象后调用,此时拿不到分组信息)。当然,这两个方
 * 法可以在 while(Matcher.find()) 的循环中调用,循环中是可以得到分组信息的)。如果确实要那样的话,
 * 我们需要使用 appendReplacement(),它可以让我们将任意数量的代码编写进执行替换的过程。通常地,
 * 我们会逐步地执行所有替换,然后调用 appendTail(),但是如果我们想模仿 replaceFirst()(或者 "替换
 * 第 n 个"),我们仅需要执行一次替换,然后调用 appendTail() 把剩余部分输入到 subf 中即可。
 * 在 while(Matcher.find()) 中,我们可以通过 "$g"(其中 "g" 是组号)的形式,来在替代字符串中直接引用
 * 被捕获的组。
 */
String[] months = new String[] {
    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月",
    "九月", "十月", "十一月", "十二月"
};
Pattern pattern = Pattern.compile("(\\w+)(\\s*:\\s*\\d{4}-)(\\d{2})(-\\d{2})");
String input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:" +
    " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。";
String result = null;
StringBuffer resultBuffer = new StringBuffer();
Matcher matcher = pattern.matcher(input);
// matcher.replaceFirst 和 matcher.replaceAll() 可以在此调用,但它们拿不到分组信息,除非将此方法
// 的调用写入 while() 循环中
while (matcher.find()) {
  // 在循环中可以得到分组信息
  String name = matcher.group(1);
  String other1 = matcher.group(2);
  String month = matcher.group(3);
  String other2 = matcher.group(4);
  matcher.appendReplacement(resultBuffer, "$1$2" +
    months[Integer.parseInt(month)] + "$4");
}
// 把剩余部分输入到 resultBuffer 中
matcher.appendTail(resultBuffer);
// 结果:以下是各个人员的出生日期信息:Aliy: 1983-十月-21; Blaine: 2000-三月-28; Tony:
// 1976-十二月-08; Joson: 1998-八月-08; Kite: 2001-十一月-20; Sanfansicico: 1991-四月-31。
System.out.println(resultBuffer);

//~------------------------------------- For Javascript ---------------------------------
<script type="text/javascript" language="javascript">
	var months = [
    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月",
    "九月", "十月", "十一月", "十二月" ];

	var pattern = /(\w+\s*:\s*\d{4}-)(\d{2})(-\d{2})/g;
	var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:" +
    " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。";
  /**
   * 分成 3 组,$1 是第 1 组所代表的值,要用引号起来,$3 是第 3 组所代表的值,$2 是第 2 组所代表
   * 的值,也就是月份,但 months["$2"] 会让 js 引擎去找 months 的 $2 的属性,因此我们对月份无能
   * 为力了。如果不为分组信息做特殊处理,我们可以使用 String.replace(Regex, String) 来处理。
   */
	var result = input.replace(pattern, "$1" + months["$2"] + "$3");
</script>

// 将 replace 函数的第二个参数使用 Function 对象
<script type="text/javascript" language="javascript">
	/**
	 * replace 把若干个参数传入此函数中:
	 * 0: 依据正则表达式和源串得到的匹配的字符串,如:Aliy: 1983-09-21
	 * 1: 正则表达式匹配到的字符串的第 1 个分组值,如:Aliy: 1983-
	 * 2: 正则表达式匹配到的字符串的第 2 个分组值,如:Aliy: 09
	 * 3: 正则表达式匹配到的字符串的第 3 个分组值,如:-21
	 * ...
	 * n: 正则表达式匹配到的字符串的第 n 个分组值
	 * n + 1: 被匹配到的字符串在源串中的索引
	 * n + 2: 源串,如:以下是各个人员的出生日期信息:Aliy: 1983-09-21; Bla ...(省略)
	 */
	function replaceAction() {
		for (var i = 0; i < arguments.length; i++) {
			alert("第 " + i + " 个参数的值为: " + arguments[i]);
		}

		// 这里可以对匹配的字符串为所欲为了
		// 这里直接返回匹配到的字符串,即不做任何替换
		return arguments[0];
	};

	var months = [
    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月",
    "九月", "十月", "十一月", "十二月" ];

	var pattern = /(\w+\s*:\s*\d{4}-)(\d{2})(-\d{2})/g;
	var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:" +
    " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。";
  // js 引擎会将一些参数传入到 replaceAction 函数中,匹配 pattern 的串将被替换成 replaceAction
  // 函数的返回值。详见 replaceAction 说明
	var result = input.replace(pattern, replaceAction);
</script>

// 完整的代码
<script type="text/javascript" language="javascript">
	function replaceAction() {
		return arguments[1] + months[parseInt(arguments[2])] + arguments[3];
	};

	var months = [
    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月",
    "九月", "十月", "十一月", "十二月" ];

	var pattern = /(\w+\s*:\s*\d{4}-)(\d{2})(-\d{2})/g;
	var input = "以下是各个人员的出生日期信息:Aliy: 1983-09-21; Blaine: 2000-02-28; Tony:" +
    " 1976-11-08; Joson: 1998-07-08; Kite: 2001-10-20; Sanfansicico: 1991-03-31。";
	var result = input.replace(pattern, replaceAction);
  // 结果:以下是各个人员的出生日期信息:Aliy: 1983-十月-21; Blaine: 2000-三月-28; Tony: 1976
  // -十二月-08; Joson: 1998-八月-08; Kite: 2001-十一月-20; Sanfansicico: 1991-四月-31。
	document.write(result);
</script>

 

Java代码  收藏代码
  1. /**  
  2.  * 这里在再举一个关于分组替换的例子:  
  3.  * 将 [长江实业(00001)] 这样的字符串替换成 ->  
  4.  * [<a href="http://org.zachary.com/stock.action?stockcode=00001">长江实业</a>(00001)]  
  5.  * 同时,做如下操作:  
  6.  *  1. 将多个空格替换成一个空格(&nbsp;)  
  7.  *  2. 将每行的前几个空格替换成四个空格(&nbsp;),行首替换成 "<p>"  
  8.  *  3. 将多个换行符替换成一个换行符,行尾替换成 "</p>"  
  9.  */   
  10.   
  11. /**  
  12.  * 编写正则表达式的思路:  
  13.  *   1. 出现 "["  
  14.  *   2. 里面只能出现非 "[" 和 "]" 任何字符(多个)  
  15.  *   3. 紧接着是括号里出现 1 到 6 位的数字  
  16.  *   4. 最后一个字符必须是 "]"  
  17.  */   
  18.   
  19. // java 的正则表达   
  20. String regExp = "\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]" ;  
  21. // javascript 的正则表达式   
  22. var regex = new  RegExp( "\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]" "g" );  
  23. var pattern = /\[([^\[^\]]+)\((\d{1 , 6 })\)/g;  
  24.   
  25. //~--------------------------------------- For Java -------------------------------------   
  26. Pattern pattern = Pattern.compile("\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]" );  
  27. String input = "北京市委常委会昨天召开会议会议    强调,要加大投资力度,加快基础设施\r\n\r\n\r\n"  +  
  28.   "   建设步伐,保持经济平稳较快发展。会议部署,今后两年共安排政府投资1200亿\r\n\r\n"  +  
  29.   " 至1500,预计带动社会投资10000亿元[长江实业(00001)]天津滨海区新增337个储备项目投资\r\n"  +  
  30.   "    规模达3000亿[香港中华煤气(00003)]广东预计明年可完成1.3万亿元投资\r\n\r\n"  +  
  31.   "       [中国自动化集团(00569)]浙江拟利用3000亿拉动内需帮扶[东方报业集团(00018)]\r\n\r\n"  +  
  32.   "[东方报业集团(00018)]中小企业。" ;  
  33. Matcher matcher = pattern.matcher(input);  
  34. String result = matcher.replaceAll("[<a href=\"http://org.zachary.com/stock.action?stockcode=$2\">$1</a>($2)]" );  
  35.   
  36. // 将两个或两个以上的空格替换成一个空格(&nbsp;)   
  37. result = result.replaceAll("(\40){2,}" "&nbsp;" );  
  38. // 将多个换行符替换成一个换行符   
  39. result = result.replaceAll("(\r\n)+" "\r\n" );  
  40. result = result.replaceAll("(?m)^\40*" "<p>&nbsp;&nbsp;&nbsp;&nbsp;" );  
  41. // (?m) 相当于 Pattern.MULTILINE 模式标记,"^" 和 "$" 分别匹配一行的开始和结束。将行尾替换成 "</p>"   
  42. result = result.replaceAll("(?m)$" "</p>" );  
  43.   
  44. System.out.println(result);  
  45.   
  46. //~------------------------------------- For Javascript ---------------------------------   
  47. <script type="text/javascript"  language= "javascript" >  
  48.   var input = "北京市委常委会昨天召开会议会议    强调,要加大投资力度,加快基础设施\r\n\r\n\r\n"  +  
  49.     "   建设步伐,保持经济平稳较快发展。会议部署,今后两年共安排政府投资1200亿\r\n\r\n"  +  
  50.     " 至1500,预计带动社会投资10000亿元[长江实业(00001)]天津滨海区新增337个储备项目投资\r\n"  +  
  51.     "    规模达3000亿[香港中华煤气(00003)]广东预计明年可完成1.3万亿元投资\r\n\r\n"  +  
  52.     "       [中国自动化集团(00569)]浙江拟利用3000亿拉动内需帮扶[东方报业集团(00018)]\r\n\r\n"  +  
  53.     "[东方报业集团(00018)]中小企业。" ;  
  54.   
  55.   var re2 -> nullgex = new  RegExp( "\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]" "g" );  
  56.   var pattern = /\[([^\[^\]]+)\((\d{1 , 6 })\)/g;  
  57.   
  58.   var result = input.replace(regex,  
  59.     "[<a href=\"http://org.zachary.com/stock.action?stockcode=$2\">$1</a>($2)]" );  
  60.   
  61.   // 将两个或两个以上的空格替换成一个空格(&nbsp;)   
  62.   result = result.replace(/\40 { 2 ,}/g,  "&nbsp;" );  
  63.   // 将多个换行符替换成一个换行符   
  64.   result = result.replace(/(\r\n)+/g, "\r\n" );  
  65.   result = result.replace("/^40*/gm" "<p>&nbsp;&nbsp;&nbsp;&nbsp;" );  
  66.   // 将行尾替换成 "</p>"   
  67.   result = result.replace(/$/gm, "</p>" );  
  68.   
  69.   document.write(result);  
  70. </script>  
/**
 * 这里在再举一个关于分组替换的例子:
 * 将 [长江实业(00001)] 这样的字符串替换成 ->
 * [<a href="http://org.zachary.com/stock.action?stockcode=00001">长江实业</a>(00001)]
 * 同时,做如下操作:
 *  1. 将多个空格替换成一个空格(&nbsp;)
 *  2. 将每行的前几个空格替换成四个空格(&nbsp;),行首替换成 "<p>"
 *  3. 将多个换行符替换成一个换行符,行尾替换成 "</p>"
 */

/**
 * 编写正则表达式的思路:
 *   1. 出现 "["
 *   2. 里面只能出现非 "[" 和 "]" 任何字符(多个)
 *   3. 紧接着是括号里出现 1 到 6 位的数字
 *   4. 最后一个字符必须是 "]"
 */

// java 的正则表达
String regExp = "\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]";
// javascript 的正则表达式
var regex = new RegExp("\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]", "g");
var pattern = /\[([^\[^\]]+)\((\d{1,6})\)/g;

//~--------------------------------------- For Java -------------------------------------
Pattern pattern = Pattern.compile("\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]");
String input = "北京市委常委会昨天召开会议会议    强调,要加大投资力度,加快基础设施\r\n\r\n\r\n" +
  "   建设步伐,保持经济平稳较快发展。会议部署,今后两年共安排政府投资1200亿\r\n\r\n" +
  " 至1500,预计带动社会投资10000亿元[长江实业(00001)]天津滨海区新增337个储备项目投资\r\n" +
  "    规模达3000亿[香港中华煤气(00003)]广东预计明年可完成1.3万亿元投资\r\n\r\n" +
  "       [中国自动化集团(00569)]浙江拟利用3000亿拉动内需帮扶[东方报业集团(00018)]\r\n\r\n" +
  "[东方报业集团(00018)]中小企业。";
Matcher matcher = pattern.matcher(input);
String result = matcher.replaceAll("[<a href=\"http://org.zachary.com/stock.action?stockcode=$2\">$1</a>($2)]");

// 将两个或两个以上的空格替换成一个空格(&nbsp;)
result = result.replaceAll("(\40){2,}", "&nbsp;");
// 将多个换行符替换成一个换行符
result = result.replaceAll("(\r\n)+", "\r\n");
result = result.replaceAll("(?m)^\40*", "<p>&nbsp;&nbsp;&nbsp;&nbsp;");
// (?m) 相当于 Pattern.MULTILINE 模式标记,"^" 和 "$" 分别匹配一行的开始和结束。将行尾替换成 "</p>"
result = result.replaceAll("(?m)$", "</p>");

System.out.println(result);

//~------------------------------------- For Javascript ---------------------------------
<script type="text/javascript" language="javascript">
  var input = "北京市委常委会昨天召开会议会议    强调,要加大投资力度,加快基础设施\r\n\r\n\r\n" +
    "   建设步伐,保持经济平稳较快发展。会议部署,今后两年共安排政府投资1200亿\r\n\r\n" +
    " 至1500,预计带动社会投资10000亿元[长江实业(00001)]天津滨海区新增337个储备项目投资\r\n" +
    "    规模达3000亿[香港中华煤气(00003)]广东预计明年可完成1.3万亿元投资\r\n\r\n" +
    "       [中国自动化集团(00569)]浙江拟利用3000亿拉动内需帮扶[东方报业集团(00018)]\r\n\r\n" +
    "[东方报业集团(00018)]中小企业。";

  var re2 -> nullgex = new RegExp("\\[([^\\[^\\]]+)\\((\\d{1,6})\\)\\]", "g");
  var pattern = /\[([^\[^\]]+)\((\d{1,6})\)/g;

  var result = input.replace(regex,
    "[<a href=\"http://org.zachary.com/stock.action?stockcode=$2\">$1</a>($2)]");

  // 将两个或两个以上的空格替换成一个空格(&nbsp;)
  result = result.replace(/\40{2,}/g, "&nbsp;");
  // 将多个换行符替换成一个换行符
  result = result.replace(/(\r\n)+/g, "\r\n");
  result = result.replace("/^40*/gm", "<p>&nbsp;&nbsp;&nbsp;&nbsp;");
  // 将行尾替换成 "</p>"
  result = result.replace(/$/gm, "</p>");

  document.write(result);
</script>

 

Javascript代码  收藏代码
  1. /**  
  2.  * 正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组来表达 ip 地址。  
  3.  *  
  4.  * 假设有一个数,要么是 250 - 255 或 10 - 99,来分析以下几种正则表达式的匹配结果:  
  5.  * ①    只要 input 出现 25[0-5] 或 [1-9]\d 就匹配,而不管 input 中出现了并不匹配的字符。  
  6.  *   var regex = /25[0-5]|[1-9]\d/;  
  7.  ×     23         -> 23       [1-9]\d  
  8.  *     235        -> 23       [1-9]\d  
  9.  *     590        -> 59       [1-9]\d  
  10.  *     254        -> 254      25[0-5]  
  11.  *     252X       -> 252      25[0-5]  
  12.  *     2          -> null  
  13.  *     K235K      -> 23       [1-9]\d  
  14.  *     AB25378XY  -> 253      25[0-5]  
  15.  *  
  16.  * ②    第 ① 种表达式被证明是失败的,由于 javascript 中没有 java 中的完全匹配的概念,因此我们采用  
  17.  *   字符前 ^ 和字符后 $ 来达到这种全部匹配的效果。  
  18.  *   var regex = /^25[0-5]|[1-9]\d$/;  
  19.  *     255        -> 255      ^25[0-5]  
  20.  *     2556       -> 255      ^25[0-5]  
  21.  *     25589      -> 255      ^25[0-5]  
  22.  *     253X       -> 253  
  23.  *     576576     -> 76       [1-9]\d$  
  24.  *     576576HW   -> null  
  25.  *       通过分析,也没有达到预期的效果,其实上面的正则表达式所表达的含义是:要么以 25[0-5] 开头,  
  26.  *   要么以 [1-9]\d 结束。因此 576576 可以匹配到 78,因为它满足了 [1-9]\d$。这里的活运算符("|"),是  
  27.  *   ^25[o-5] 整体和 [1-9]\d$ 整体进行或运算,而不是 [0-5] 和 [1-9] 进行或运算,关于 [0-5] 和  
  28.  ×   [1-9] 进行或运算的例子,参考 ④。  
  29.  *  
  30.  * ③    这个时候,我们需要将 25[0-5]|[1-9]\d 用括弧给括起来,使其作为一个整体,并加 ^ 和 $,这样  
  31.  *   就达到了我们所需要的效果。  
  32.  *   var regex = /^(25[0-5]|[1-9]\d)$/;  
  33.  *     23         -> 23, 23   [1-9]\d  
  34.  *     235        -> null  
  35.  *     590        -> null  
  36.  *     254        -> 254, 254 25[0-5]  
  37.  *     252X       -> null  
  38.  *     5          -> null  
  39.  *     88         -> 88, 88   [1-9]\d  
  40.  *     066        -> null  
  41.  *       这里匹配的结果只所以出现两次,是因为加了括弧,它同时是分组的含义,第一个匹配的是匹配的完整结  
  42.  *   果,第二个匹配的是第一个分组的值。  
  43.  *  
  44.  * ④    对 ② 的补充说明,[0-5] 和 [1-9] 进行或运算。  
  45.  *   var regex = /25([0-5]|[1-9])\d/;  
  46.  *     253        -> null  
  47.  *     2532       -> 2532, 3  
  48.  *     2578A      -> 2578, 7  
  49.  *     XY2580UK   -> 2580, 8  
  50.  *       之所以 XY2580UK 也可以被匹配,原因同 ①,这不是完全匹配的正则表达式。  
  51.  *   
  52.  * ip 地址的每段只能从 0 到 255,数字前不能有 0,分解这些数字如下:  
  53.  *   ① 0 - 9     -> \d  
  54.  *   ② 10 - 99   -> [1-9]\d  
  55.  *   ③ 100 - 199 -> 1\d{2}  
  56.  *   ④ 200 - 249 -> 2[0-4]\d  
  57.  *   ⑤ 250 - 255 -> 25[0-5]  
  58.  *   
  59.  × 以下是两种情况的正则表达式以匹配 ip 地址:  
  60.  * ① (\d{1,3}.){3}(\d{1,3}) (\d{1,3}.){3} 再连最后一个数字:  
  61.  * /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/;  
  62.  * ② (\d{1,3})(.\d{1,3}){3} 起始一个数字再连 (.\d{1,3}){3}:  
  63.  * /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)){3}$/;  
  64.  *  
  65.  * 这个正则表达式写的复杂了些,它表明每段的数字的开头不能是 0。如果开头可以为 0,表达式要稍微简洁些。  
  66.  */  
来源:http://zachary-guo.iteye.com/blog/542192
分享到:
评论

相关推荐

    精通正则表达式~~~

    精通正则表达式第三版 搜集于网络 前言..........I 第1章:正则表达式入门.... 1 解决实际问题... 2 作为编程语言的正则表达式... 4 以文件名做类比... 4 以语言做类比... 5 正则表达式的知识框架... 6 对于...

    C#正则表达式分解和转换IP地址实例(C#正则表达式大全 c#正则表达式语法)

    是我发了不少时间整理的C#的正则表达式,新手朋友注意一定要手册一下哦,这样可以节省很多写代码的时间。下面进行了简单总结

    初学者python笔记(re模块、正则表达式完全解析)

    今天总结一下正则表达式,它用来解决模糊匹配的问题,几乎在所有编程语言中都可以用,尤其在python爬虫中,它是一门必修知识; 所谓模糊匹配,就是在匹配字符串中,有一部分是确定的,另一部分是不确定的值但有范围...

    js 玩转正则表达式之语法高亮

    学了几天正则,差不多该总结整理写成果了,通过分析2位大神的代码,整理出来的一篇很实用的

    Python正则表达式经典入门教程

    本文实例总结了Python正则表达式基本用法。分享给大家供大家参考,具体如下: 正则表达式在平时做文本处理(爬虫程序去解析html中的字段,在分析log文件的时候需要抓取一些关键数据)的时候经常会用到。一般我们会...

    毕业设计 词法分析器 生成工具 摘要与目录

    构造语言识别器的过程为:首先,从词法分析器生成工具读入正则表达式,将该正则表达式转换成等价的不确定的有限自动机,从而构造出确定的有限自动机,然后构造出确定的有限自动机的状态转换表,词法分析器生成工具...

    Java编码规范总结

    修复建议:String的split方法传递的参数是正则表达式,正则表达式本身用到的字符需要转义,如:句点符号“.”,美元符号“$”,乘方符号“^”,大括号“{}”,方括号“[]”,圆括号“()” ,竖线“|”,星号“*”,...

    java基础总结.xmind

    IO、面向对象Object类、API、集合体系、IO体系、面向对象、多线程、递归、相互转换、正则表达式

    python爬虫课程要点.docx

    4)正则表达式:强大的字符串处理工具,有自己特定的语法结构,实现字符串的检索、替换、匹配、验证。 5)函数:end(),返回指定分组的结束位置,默认返回正则表达式所匹配到的最后一个字符的索引。 6)...

    JavaScript王者归来part.1 总数2

     10.4.1 RegExp对象——利用正则表达式实现全文检索   10.4.2 RegExp的实例属性   10.5 强大的正则表达式   10.5.1 分析正则表达式的局部   10.5.2 一个例子--强大的在线编辑器   10.5.3 构造新的文法--...

    C++转JAVA入门总结

    5. 工具类(数据容器、日期、正则表达式……) 6. JAVA流、文件、IO 7. JAVA异常 8. JAVA继承 1. 抽象类与抽象方法 2. JAVA接口 3. JAVA泛型编程 4. JAVA序列化 5.JAVA网络与多线程 6. JAVA类生命周期

    Python编程中常用的12种基础知识

    Python 编程中常用的12 种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序、去重,字典排序,字典、列表、字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进制转换,python 调用...

    小白福利|python编程必须要掌握的这12种基础知识

    Python 编程中常用的12 种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序、去 重,字典排序,字典、列表、字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化 输出,进制转换,Python ...

    shell脚本中28个特殊字符的作用简明总结

    1. #注释作用, #! 除外此外, 在参数替换 echo ${PATH#*:} 这里不表示注释, 数制转换, 不表示注释 echo $((2#101011)) 2. ; 命令行分隔符, 可以在一行中写... 表示上一级目录正则表达式中作为单个字符匹配5. “”, ‘’

    c#搜集的帮助类 c#搜集的帮助类

    22. 正则表达式 --------- RegexHelper.cs 23. 分页操作 24. UBB编码 25. Url重写 26. Object拓展 --------- ObjectExtension.cs 27. Stream的拓展 ------ StreamExtension.cs 28. CSV文件转换 29. Chart图形 30. H5...

    Java基础知识点总结.docx

    二十、 正则表达式:其实是用来操作字符串的一些规则★★★☆ 135 二十一、 设计模式★★★★★ 136 设计模式简介 136 单例设计模式:★★★★★ 156 工厂模式★★★★★ 159 抽象工厂模式★★★★★ 163 建造者模式...

    C#实训教程

    7 字符串与正则表达式 132 7.1 System.String类 132 7.2 StringBuilder成员 135 7.3 字符串的格式化 138 7.4 正则表达式概述 142 7.5 内容总结 149 7.6 独立实践 150 8 集合 151 8.1 集合 151 8.2 索引器 152 8.3 ...

    TUndeL:我基于MVC架构和PHP技术将其命名为TUndeL(两个下划线)的微型框架

    应用名称:TUndeL框架当前版本:0.8发展商:新浪 ...添加正则表达式模式作为在路由参数中使用的规则 方法 : addRule getRule getRoute(RouteName,参数) getNormalUrl getRoutes [返回所有路线] 获取

    leetcode数组下标大于间距-LeetCode:秋招刷题总结

    正则表达式匹配 Hard 字符串 | 动态规划 14 最长公共前缀 Easy 字符串 15 三数之和 Medium 数组 | 双指针 18 四数之和 Medium 数组 | 双指针 19 删除链表的倒数第N个节点 Medium 链表 20 有效的括号 Easy 字符串 23 ...

Global site tag (gtag.js) - Google Analytics