大家好,今天给各位分享Java编程:正则表达式应用详解的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
正则表达式描述了一种字符串匹配模式(pattern),可以用来检查字符串中是否包含某个子字符串,替换匹配的子字符串,或者提取满足某个条件的字符串。子串等
例子:runoo+b,可以匹配runoob、runooob、runooooooob等。+号表示前一个字符必须至少出现一次(一次或多次)。 runoo*b 可以匹配runob、runoob、runooooooob等。*号表示该字符可能不出现,也可能出现一次或多次(0次、或1次、或多次)。 color?r 可以匹配颜色或颜色,问号表示前一个字符最多只能出现一次(0次,或者1次)。构造正则表达式的方式与创建数学表达式的方式相同。也就是说,使用多个元字符和运算符小表达式可以组合在一起创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。正则表达式是由普通字符(例如字符a 到z)和称为“元字符”的特殊字符组成的文字模式。模式描述搜索文本时要匹配的一个或多个字符串。正则表达式用作将字符模式与搜索字符串进行匹配的模板。
普通字符
普通字符包括未明确指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
非打印字符
非打印字符也可以是正则表达式的一部分。下表列出了表示非打印字符的转义序列:
字符描述cx 匹配x 指定的控制字符。例如,cM 匹配Control-M 或回车符。 x 的值必须是A-Z 或a-z 之一。否则,c 将被视为文字“c”字符。 f 匹配换页符。相当于x0c 和cL。 n 匹配换行符。相当于x0a 和cJ。 r 匹配回车符。相当于x0d 和cM。 s 匹配任何空白字符,包括空格、制表符、换页符等。相当于[ fnrtv]。请注意,Unicode 正则表达式将匹配全角空白字符。 S 匹配任何非空白字符。相当于[^ fnrtv],其中“^”表示“不”t匹配制表符。相当于x09 和cI。 v 匹配垂直制表符。相当于x0b 和cK。US-ASCII控制字符US-ASCII 控制字符
特殊字符
所谓特殊字符,就是具有特殊含义的字符,比如上面提到的runoo*b 中的*,它简单的表示任意字符串的含义。如果要查找字符串中的*符号,需要对*进行转义,即在其前面添加: runo*ob来匹配runo*ob。
许多元字符在尝试匹配时需要特殊处理。要匹配这些特殊字符,必须首先对这些字符进行“转义”,即将反斜杠字符“”放在它们前面。下表列出了正则表达式中的特殊字符:
特殊字符描述$ 匹配输入字符串的结尾。多行属性,$ 也匹配"n" 或"r"。要匹配$ 字符本身,请使用$。 () 标记子表达式的开始和结束。可以获得子表达式以供以后使用。要匹配这些字符,请使用( 和)。匹配前面的子表达式零次或多次。要匹配* 字符,请使用*。 + 匹配前面的子表达式一次或多次。要匹配+ 字符,请使用+。匹配除换行符n 之外的任何单个字符。为了匹配。 使用。 [标记括号表达式的开始。要匹配[,请使用[。匹配前面的子表达式零次或一次,或指定非贪婪限定符。为了匹配?字符,使用? 将下一个字符标记为特殊字符、文字字符、反向引用或八进制转义字符。例如,“n”匹配字符“n”。 "n" 匹配换行符。序列"\" 匹配"",而"(" 匹配"("。^ 标记限定符表达式的开头。要匹配{,请使用{.| 指定两项之间的选择。 要匹配|,使用|。
限定符
限定符用于指定正则表达式的给定组件必须出现多少次才能满足匹配。 n,m}共6种。
正则表达式的限定符是:
特殊字符描述与前面的子表达式匹配零次或多次。例如,zo* 匹配“z”和“zoo”。 * 相当于{0,}。 + 匹配前面的子表达式一次或多次。例如,“zo+”匹配“zo”和“zoo”,但不匹配“z”。 + 相当于{1,}。匹配前面的子表达式零次或一次。例如,“做什么?”可以匹配"do", "does", "does", "doxy" 中的"do"。相当于{0,1}。 {n}n 是非负整数。匹配一定次数的n次。例如,“o{2}”与“Bob”中的“o”不匹配,但与“food”中的两个o 匹配。 {n,}n 是非负整数。至少匹配n次。例如,“o{2,}”与“Bob”中的“o”不匹配,但与“foooood”中的所有o 匹配。 “o{1,}”相当于“o+”。 “o{0,}”相当于“o*”。 {n,m}m 和n 都是非负整数,其中n=m。至少匹配n 次,最多匹配m 次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。 “o{0,1}”相当于“o?”。请注意,逗号和两个数字之间不能有空格。
例:
在HTML 文档中搜索H1 标记中包含的部分标题。文档中的文本如下所示:
1、介绍正则表达式
则具有表达式:
".*" 表达式匹配从开始的小于号() 到结束的H1 标记的大于号() 的所有内容。
贪婪、非贪婪
* 和+ 限定符是贪婪的。(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。非贪婪或最小匹配只能通过添加? 来实现。在他们之后。
例如,在上面的例子中,当我们要匹配起始和结束H1标签时,表达式如下:
".*?"如果只想匹配开头的H1标签,则表达式为:
"w+?"通过放置?在*、+ 或? 之后限定符时,表达式从“贪婪”表达式转换为“非贪婪”表达式或最小匹配。
定位符
定位器使您能够将正则表达式固定到行的开头或结尾。它们还使您能够创建出现在单词内、单词开头或单词末尾的正则表达式。
定位器用于描述字符串或单词的边界。 ^ 和$ 分别指字符串的开头和结尾。 b 描述单词的前边界或后边界。 B 表示非单词边界。
正则表达式定位器是:
字符描述^ 与输入字符串的开头匹配。如果设置了RegExp 对象的Multiline 属性,则^ 还匹配n 或r 之后的位置,而$ 则匹配输入字符串末尾的位置。如果设置了RegExp 对象的Multiline 属性,$ 也会匹配n 或r 前面的位置。 b 匹配单词边界,即单词与空格或标点符号之间的位置。 B 非单词边界匹配。注意:您不能将限定符与定位器一起使用。由于仅考虑换行符或单词边界之前或之后的边界,因此不允许使用^* 等表达式。
选择
使用括号“(",")”将所有选择括起来,并用| 分隔相邻的选择。 h(e|is) 匹配he 和his。
使用括号会有另一种效果,这样相关的匹配项就会被缓存。这时可以在第一个选项前面使用?来消除这种缓存效应。
其中,是非捕获元素之一,非捕获元素有两个:=和?这两个还有更多的意义。前者是正预取,无论如何,后者是负预取。
反向引用
在正则表达式模式或模式的一部分周围添加括号将导致关联的匹配存储在临时缓冲区中,每个捕获的子匹配按照它们在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从1 开始,最多可存储99 个捕获的子表达式。每个缓冲区都可以使用n 进行访问,其中n 是标识特定缓冲区的一位或两位十进制数。
您可以使用非捕获元字符?=或?覆盖capture(不懂也没关系?=、我们后面会提到),忽略相关匹配的保存。
反向引用最简单、最有用的应用之一是能够找到文本中两个相同的相邻单词的匹配项。以下面的句子为例:
汽油价格上涨了吗?
b([a-z]+) 1b这是一个js示例:
var str="汽油价格上涨";
var patt1=/b([a-z]+) 1b/ig;
document.write(str.match(patt1));这里的1代表第一个括号的表达式匹配缓存,/ig代表忽略大小写,全局匹配(/i不区分大小写;/g全局匹配全局;/m多行模式multi。这个对应Pattern。 compile(String regex, int flag) java的flag参数,后面会写)。匹配结果为:
是是的向上
反向引用还将通用资源指示符(URI) 分解为其组件。假设您要将以下URI 分解为协议(ftp、http 等)、域地址和页面/路径:
例子
var str="http://www.runoob.com:80/html/html-tutorial.html";
var patt1=/(w+)://([^/:]+)(:d*)?([^# ]*)/;
arr=str.match(patt1);
for (var i=0; i arr.length; i++) {
文档.write(arr[i]);
文档.write("
");
}第三行代码str.match(patt1)返回一个数组。示例中的数组包含5 个元素。索引0 对应于整个字符串,索引1 对应于第一个匹配字符(在括号中),依此类推。
第一个括号子表达式捕获网址的协议部分(w 匹配字母、数字和下划线。相当于“[A-Za-z0-9_]”。)。该子表达式匹配前面有冒号和两个正斜杠的任何单词。
第二个括号子表达式捕获地址的域地址部分。子表达式匹配: 以及/后面的一个或多个字符。
第三个括号子表达式捕获端口号(如果指定了)。该子表达式匹配冒号后面的零个或多个数字。该子表达式只能重复一次。
最后,第四个括号子表达式捕获由网址指定的路径和/或页面信息。此子表达式匹配不包含# 或空格字符的任何字符序列。
将正则表达式应用于上面的URI,每个子匹配包含以下内容:
第一个括号子表达式包含http。第二个括号子表达式包含www.runoob.com。第三个括号子表达式包含:80。第四个括号子表达式包含/html/html-tutorial.html 的其余元素。特点
字符描述:当字符紧跟在任何其他限定符(*、+、{n}、{n,}、{n,m})之后时,匹配模式是非贪婪的。非贪婪模式尽可能匹配搜索到的字符串,而默认贪婪模式则尽可能匹配搜索到的字符串。例如,对于字符串“oooo”、“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。 (pattern) 匹配pattern 并获得此匹配。获得的匹配可以通过Matcher的group(int group)方法获得; (?pattern) 匹配了模式,但没有获得匹配结果,这意味着这是一个未获得的匹配,不会存储以供将来使用。这使用“或”字符(|) 来组合模式的各个部分。例如,“industry|industries”缩写为“industr(?y|ies)”。 (?=pattern) 正向正向查找,在任何字符串匹配模式的开头匹配搜索字符串。这是非提取匹配,即不需要提取该匹配以供以后使用。例如,“Windows(?=95|98|NT|2000)”可以匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预取不消耗字符。(不消耗字符是指,当匹配开始的时候,预查Windows后面字符,不管后面是不是95|98|NT|2000,那么下一次匹配会紧跟着Windows后面进行匹配)(?pattern) 正向负向查找,匹配任何不匹配pattern的字符串开头的搜索字符串。未获得匹配。例如,“Windows(?95|98|NT|2000)”可以匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预取不消耗字符。 (?=pattern) 反向正预检查与正向预检查类似,但方向相反。例如,“(?=95|98|NT|2000)Windows”可以匹配“2000Windows”中的“Windows”,但无法匹配“3.1Windows”中的“Windows”。 (? 反向负查找与正向负查找类似,但方向相反。例如,"(?预查又称前瞻(正向预查)后顾(反向预查),对于这个概念中的前、后的规定这里说明一下,对于正则匹配时的“前”即为文档流还未解析到的部分;那么也就是说“后”指的则是已经解析过的部分d 匹配数字字符。相当于[0-9]。D 匹配非数字字符相当于[^0-9]。 相当于"[A-Za-z0-9_]"。非字母、数字和下划线。 xn 匹配n,其中n 是十六进制转义值。相当于"x04" "1" 可在正则表达式中用于匹配num,其中num 是正整数,例如"(.) 1"。匹配两个连续的相同字符。un 匹配n,其中n 是由四个十六进制数字表示的Unicode 字符,例如,u00A9 匹配从左侧开始的版权符号,按照优先顺序进行评估。算术表达式。
优先级相同的操作从左到右执行,优先级不同的操作从高到低执行。下表从最高到最低说明了各种正则表达式运算符的优先顺序:
正则表达式说明转义字符(), (?), (?=), []圆括号和方括号*, +, {n}, {n,}, {n,m} 限定符^, $ , 任何元字符、任何字符锚点和序列(即:位置和顺序)|替换、“或”操作字符的优先级高于替换运算符,使“m|food”匹配“m”或“food”。要匹配“心情”或“食物”,请使用括号创建子表达式,结果为“(m|f)ood”。
运算符优先级
java.util.regex包主要包含以下三个类:
图案类:
模式对象是正则表达式的编译表示。 Pattern 类没有公共构造函数。要创建Pattern对象,必须首先调用其公共静态编译方法,该方法返回Pattern对象。此方法接受正则表达式作为其第一个参数。匹配器类:
Matcher 对象是解释和匹配输入字符串的引擎。与Pattern 类一样,Matcher 没有公共构造函数。需要调用Pattern对象的matcher方法来获取Matcher对象。模式语法异常:
PatternSyntaxException 是一个非强制异常类,表示正则表达式模式中的语法错误。实例导入java.util.regex.*;
正则表达式示例1类{
公共静态无效主(字符串参数[]){
字符串内容="我是菜鸟" +
"来自runoob.com。";
字符串模式=".*runoob.*";
boolean isMatch=Pattern.matches(模式, 内容);
System.out.println("字符串中是否包含"runoob"子字符串?" + isMatch);
}
}结果:
该字符串是否包含“runoob”子字符串?真的
捕获组捕获组是将多个字符视为单个单元的方法。它是通过将括号内的字符分组来创建的。
例如,正则表达式(dog) 创建一个包含“d”、“o”和“g”的组。
捕获组的编号是通过从左到右计算其左括号来进行的。例如,在表达式((A)(B(C))) 中,有四个这样的组:
((A)(B(C)))
(一个)
(公元前))
(三)
您可以通过调用匹配器对象的groupCount 方法来查看表达式有多少个组。 groupCount方法返回一个int值,表示匹配器对象当前有多个捕获组。
还有一个特殊的组(group(0)),它代表整个表达式。该组不包含在groupCount 的返回值中。
例如导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
公共类正则表达式匹配
{
公共静态无效主(字符串参数[]){
//根据指定的模式在字符串中搜索
String line="此订单是针对QT3000 下的!好的?";
字符串模式="(\D*)(\d+)(.*)";
//创建模式对象
模式r=Pattern.compile(pattern);
//现在创建匹配器对象
匹配器m=r.matcher(line);
如果(m.find( )) {
System.out.println("找到值:" + m.group(0) );
System.out.println("找到值:" + m.group(1) );
System.out.println("找到值:" + m.group(2) );
System.out.println("找到值:" + m.group(3) );
} 别的{
System.out.println("不匹配");
}
}
}运行结果:
发现价值: 该订单是QT3000!好的?
找到value: 该订单是为QT 下的
发现值: 3000
发现价值:好的?
反斜杠 在 Java 中表示转义字符,这意味着 在 Java 拥有预定义的含义。匹配特殊字符如. or { 或[ 或( 或? 或$ 或^ 或* ,需要在前面加上\。例如匹配.时,在Java中应该写成\.但对于正则表达式来说,则是. 匹配时,在Java中写为\,但对于正则表达式,则为\. 例如,匹配中文时,使用"[\u4e00-\u9fa5]+"(4e00- 9fa5是汉字的Unicode编码范围)APIPatternPattern.matches()检查正则表达式模式是否匹配一段文本最直接的方法是调用静态方法,Pattern.matches()方法适合于检查某个模式是否在文本中出现过一次
如果需要匹配多个匹配项,甚至可以输出不同的匹配文本。您需要通过Pattern.compile()方法获取Pattern实例。
public static Patterncompile(String regex, int flags)Pattern.CANON_EQ,当且仅当两个字符的“规范分解”完全相同时,才会考虑匹配。例如,使用此标志后,表达式“au030A”将匹配“?”。一般来说,字符串相等性是根据规范等价来判断的。即使两个规范等效字符串的底层Unicode 标量不同,只要它们的语义和表示形式一致,它们就被认为是相等的。规范相等性(canonical equivalence)是Unicode字符集编码中的规范。简单地说,两个不同的代码点代表同一个字符。
代码点(code point)是字符集编码后出现的概念。字符集(Code Set)是一个集合,集合中的元素是字符,比如ASCII字符集,其中的字符有‘A’、‘B’等字符。为了在计算机中处理字符集,必须将字符集数字化,这意味着给字符集中的每个字符一个编号。如果你想在计算机程序中使用字符,你就可以使用这个数字。于是就出现了编码字符集,称为编码字符集(Coded Code Set)。编码字符集中的每个字符都对应一个数字。那么这个数字就是代码点。
Pattern.CASE_INSENSITIVE(?i) 默认情况下,不区分大小写的匹配仅适用于US-ASCII 字符集。该标志使表达式无论大小写都匹配。要执行Unicode 字符的明确匹配,只需将UNICODE_CASE 与此标志结合起来即可。 Pattern.COMMENTS(?x) 该模式下,匹配时会忽略(正则表达式中的)空格字符(不是指表达式中的“s”,而是指空格、制表符、回车等)。 )。以# 开头的注释将被忽略,直到该行结束。 Pattern.DOTALL(?s) 在此模式下,表达式"."可以匹配任何字符,包括行尾。默认情况下,表达式“.”与行终止符不匹配。 Pattern.MULTILINE(?m) 在此模式下,"^" 和"$" 分别匹配行的开头和结尾。此外,“^”仍然匹配字符串的开头,“$”也匹配字符串的结尾。默认情况下,这两个表达式仅匹配字符串的开头和结尾。 Pattern.UNICODE_CASE(?u) 在此模式下,如果还启用CASE_INSENSITIVE 标志,它将不区分大小写地匹配Unicode 字符。默认情况下,不区分大小写的匹配仅适用于US-ASCII 字符集。 Pattern.UNIX_LINES(?d) 在该模式下,只有"n"被识别为行尾,与"."、"^相同
’,以及’$’进行匹配。Pattern.LITERAL,当指定此标志时,指定模式的输入字符串将被视为字面字符序列。输入序列中的元字符或转义序列将没有特殊含义。只有CASE_INSENSITIVE 和 UNICODE_CASE跟这个flag一块使用时,保留他们的规则,由于所有元字符和转移字符都当成字面字符被看待,所以其他flag没有作用。Pattern.UNICODE_CHARACTER_CLASS使用Unicode中的预定义字符集(d、w)。由于安卓默认支持Unicode预定义字符集,所以这个标志对android没有影响。Pattern.matcher()一旦获得了Pattern对象,接着可以获得Matcher对象。Matcher 示例用于匹配文本中的模式.示例如下 Matcher matcher = pattern.matcher(text);String text = "This is the text to be searched " + "for occurrences of the http:// pattern."; String patternString = ".*http://.*"; Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);//忽略大小写 Matcher matcher = pattern.matcher(text); boolean matches = matcher.matches(); System.out.println("matches = " + matches);Matcher通过Pattern 的matcher() 方法可以创建一个Matcher。 Matcher 类的 matches() 方法用于在文本中匹配正则表达式 boolean matches = matcher.matches();lookingAt()lookingAt() 与matches() 方法类似,最大的不同是,lookingAt()方法对文本的开头匹配正则表达式;而matches() 对整个文本匹配正则表达式。换句话说,如果正则表达式匹配文本开头而不匹配整个文本,lookingAt() 返回true,而matches() 返回false。 示例: String text = "This is the text to be searched " + "for occurrences of the http:// pattern."; String patternString = "This is the"; Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(text); System.out.println("lookingAt = " + matcher.lookingAt()); System.out.println("matches = " + matcher.matches());上面的例子分别对文本开头和整个文本匹配正则表达式 “this is the”. 匹配文本开头的方法(lookingAt()) 返回true。对整个文本匹配正则表达式的方法 (matches()) 返回false,因为整个文本包含多余的字符,而 正则表达式要求文本精确匹配”this is the”,前后又不能有额外字符。find() + start() + end()find() 方法用于在文本中查找出现的正则表达式,文本是创建Matcher时,通过 Pattern.matcher(text) 方法传入的。如果在文本中多次匹配,find() 方法返回第一个,之后每次调用 find() 都会返回下一个。 start() 和 end() 返回每次匹配的字串在整个文本中的开始和结束位置。实际上, end() 返回的是字符串末尾的后一位,这样,可以在把 start() 和 end() 的返回值直接用在String.substring() 里。 String text = "This is the text which is to be searched " + "for occurrences of the word "is"."; String patternString = "is"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text); int count = 0; while(matcher.find()) { count++; System.out.println("found: " + count + " : " + matcher.start() + " - " + matcher.end()); }结果: found: 1 : 2 - 4 found: 2 : 5 - 7 found: 3 : 23 - 25 found: 4 : 70 - 72reset()reset() 方法会重置Matcher 内部的 匹配状态。当find() 方法开始匹配时,Matcher 内部会记录截至当前查找的距离。调用 reset() 会重新从文本开头查找。 也可以调用 reset(CharSequence) 方法. 这个方法重置Matcher,同时把一个新的字符串作为参数传入,用于代替创建 Matcher 的原始字符串。group()前面说到,我们可以利用find()方法找到匹配,并可以利用start()、end()拿到匹配的字符。 还要一种简单的用法,就是group()。使用group(int groupNo) 方法访问一个分组。 group(0);始终返回整个正则表达式,且不会再groupCount()中记录。 int count = 0; String text = "is a is b"; String patternStr = "(is) ([a-z])"; Pattern pattern = Pattern.compile(patternStr); Matcher matcher = pattern.matcher(text); while (matcher.find()){ count++; for (int i = 0; i<= matcher.groupCount(); i++) { System.out.println("find #"+count+":group"+i+" "+matcher.group(i)); } }结果: find #1:group0 is a find #1:group1 is find #1:group2 a find #2:group0 is b find #2:group1 is find #2:group2 b 嵌套分组 ((John) (.+?)) 当遇到嵌套分组时, 分组编号是由左括号的顺序确定的。上例中,分组1 是那个大分组。分组2 是包括John的分组,分组3 是包括 .+? 的分组。 上例正则表达式最外层加上小括号 "((is) ([a-z]))"运行结果为: find #1:group0 is a find #1:group1 is a find #1:group2 is find #1:group3 a find #2:group0 is b find #2:group1 is b find #2:group2 is find #2:group3 b 正则表达式((A)(B(C)))则对应的分组为: ((A)(B(C)))(A)(B(C))(C)replaceAll() + replaceFirst()replaceAll() 和 replaceFirst() 方法可以用于替换Matcher搜索字符串中的一部分。replaceAll() 方法替换全部匹配的正则表达式,replaceFirst() 只替换第一个匹配的。 还有一点就是:在处理之前,Matcher 会先重置。所以这里的匹配表达式从文本开头开始计算。 String text = "John writes about this, and John Doe writes about that," + " and John Wayne writes about everything."; String patternString1 = "((John) (.+?)) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); String replaceAll = matcher.replaceAll("Joe Blocks "); System.out.println("replaceAll = " + replaceAll); String replaceFirst = matcher.replaceFirst("Joe Blocks "); System.out.println("replaceFirst = " + replaceFirst);replaceAll =Joe Blocksabout this, andJoe Blockswrites about that,andJoe Blockswrites about everything. replaceFirst =Joe Blocksabout this, and John Doe writes about that,and John Wayne writes about everything.appendReplacement() + appendTail()appendReplacement() 和 appendTail() 方法用于替换输入文本中的字符串短语,并把替换后的字符串附加到一个StringBuffer中,我们可以从StringBuffer拿到替换后的字符串。 appendReplacement()方法可以替换文本中的数据,并且把上一次匹配的结束位置到替换字符的结束附加到StringBuffer中。 当匹配结束,文本的末尾可能还有一部分没有匹配到的文本,可以使用appendTail()把剩余没有匹配到的字段附加到StringBuffer。 String text = "John writes about this, and John Doe writes about that," + " and John Wayne writes about everything."; String patternString1 = "((John) (.+?)) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); StringBuffer stringBuffer = new StringBuffer(); while(matcher.find()){ matcher.appendReplacement(stringBuffer, "Joe Blocks "); System.out.println(stringBuffer.toString()); } matcher.appendTail(stringBuffer);//把剩余的“writes about everything.”添加到末尾 System.out.println(stringBuffer.toString());Joe Blocks Joe Blocksabout this, and Joe BlocksJoe Blocks about this, and Joe Blockswrites about that, and Joe BlocksJoe Blocks about this, and Joe Blocks writes about that, and Joe Blockswrites about everything.同时appendReplacement方法的第二个参数还可以通过设置"$n"(n的范围是"0"-"9")和"${groupName}"(groupName是在正则表达式中定义的组名,"(?pattern)"),来获取正则表达式中的group。api代码实现如下: public Matcher appendReplacement(StringBuffer sb, String replacement) { sb.append(input.substring(appendPos, start()));//添加从上次匹配结束位置--当前匹配开始位置截取的字符 appendEvaluated(sb, replacement);//添加要替换的文本 appendPos = end();//更新游标 return this; } ... ... private void appendEvaluated(StringBuffer buffer, String s) { boolean escape = false; boolean dollar = false; boolean escapeNamedGroup = false; int escapeNamedGroupStart = -1; for (int i = 0; i< s.length(); i++) { char c = s.charAt(i); if (c == "\" && !escape) { escape = true; } else if (c == "$" && !escape) { dollar = true; } else if (c >= "0" && c<= "9" && dollar) {//上个字符为$则匹配group0-group9 buffer.append(group(c - "0")); dollar = false; } else if (c == "{" && dollar) {//${groupName} escapeNamedGroup = true; escapeNamedGroupStart = i; } else if (c == "}" && dollar && escapeNamedGroup) { String namedGroupName = s.substring(escapeNamedGroupStart + 1, i); buffer.append(group(namedGroupName));//${groupName} dollar = false; escapeNamedGroup = false; } else if (c != "}" && dollar && escapeNamedGroup) { continue; } else { buffer.append(c); dollar = false; escape = false; escapeNamedGroup = false; } }改变上一个例字为: String text = "John writes about this, and John Doe writes about that," + " and John Wayne writes about everything."; String patternString1 = "((?John) (.+?)) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); StringBuffer stringBuffer = new StringBuffer(); while(matcher.find()){ matcher.appendReplacement(stringBuffer, "Joe ${group1} $3 "); System.out.println(stringBuffer.toString()); } matcher.appendTail(stringBuffer);//把剩余的“writes about everything.”添加到末尾 System.out.println(stringBuffer.toString());新的输出结果为: Joe Johnwrites Joe John writesabout this, and Joe JohnDoeJoe John writes about this, and Joe John Doewrites about that, and Joe JohnWayneJoe John writes about this, and Joe John Doe writes about that, and Joe John Waynewrites about everything.over~~~~【Java编程:正则表达式应用详解】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
正则表达式太神奇了!以前没接触过,现在感觉很有用
有11位网友表示赞同!
学习Java,怎么能绕开正则表达式的呢?必须掌握这个技能!
有19位网友表示赞同!
Java用的正则表达式,真的强大啊!可以处理各种文本需求
有7位网友表示赞同!
看不懂这些符号,是不是得花时间好好琢磨一下?
有12位网友表示赞同!
今天遇到一个问题要用到正则表达式,感觉好难用。。。
有13位网友表示赞同!
希望这篇文章能帮我理解Java用的正则表达式的用法!
有18位网友表示赞同!
我想学习做数据清洗工作,正则表达式应该很有帮助吧?
有11位网友表示赞同!
Java 的正则表达式语法真的很详细!以后可以参考一下
有10位网友表示赞同!
想了解 Java 正则表达式的应用场景,这篇文章应该是很好的入门指南
有20位网友表示赞同!
学习代码一定要结合实际项目,才能更好地理解正则表达式的运用
有10位网友表示赞同!
看了很多学习资料,还是觉得用实例讲解最好懂!希望这篇文章中能有例子
有8位网友表示赞同!
正则表达式在网页开发中经常用到吗?
有20位网友表示赞同!
感觉这些复杂的符号让人头疼,真的需要好好练习才能掌握!
有7位网友表示赞同!
以前只用过简单的正则表达式,现在准备学习更高级的用法
有12位网友表示赞同!
希望这篇文章能讲解一些常见的使用技巧,提高我的效率
有7位网友表示赞同!
学习新的技术总是充满挑战,加油!
有18位网友表示赞同!
文章讲得不错,希望能有更多关于 Java 正则表达式的应用案例
有7位网友表示赞同!
感觉正则表达式学习起来还是挺有意思的,很有成就感!
有18位网友表示赞同!