@myron-lee
2015-07-18T05:56:31.000000Z
字数 2033
阅读 3714
Blog
最近项目用到正则表达式比较多,发现正则表达式非常强大,可以拿来做很多事情。以前只知道拿它去判断一个字符串是否符合一个模式,或者拿来在文本中查找感兴趣的字符串。其实,还可以用它编辑处理文本。事实上,查找依托于匹配,编辑依托于查找,根基还是匹配。
正则表达式有独特的语法,有元字符。比如.
会匹配任意字符(除去换行符\n
)。如果我们想.
只匹配.
,那么我们就需要转义。
问题来了,如果我们这样定义String line = "\. hello world";
,会出现非法转义符
错误。因为java无法转义.
。所以我们需要这样定义String line = "\\. hello world";
,这样java就不会去转义.了,因为第二个\
被第一个\
转义了,它不再是转义符了。
在Python里面可以这么定义'''\. hello world'''
,Python可以定义raw string,raw string中的\不是转义字符了。
项目中有个需求,要把{0} variable {1} should begin with {2}
与bala variable bobo should begin with lala
匹配。我的做法是将{0} variable {1} should begin with {2}
转换为.* variable .* should begin with .*
,然后用.* variable .* should begin with .*
去匹配bala variable bobo should begin with lala
。
将{0} variable {1} should begin with {2}
转换为.* variable .* should begin with .*
就需要用到正则表达式的编辑文本功能,先匹配{0}``{1}``{2}``{3}
等等,然后将它们全部替换为·*
。(注意,{
和}
也是元字符需要转义,正则表达式是\{\d+\}
,转换到java string就是\\{\\d+\\}
)
//java
String patternString = "\\{\\d+\\}";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(resultString);
resultString = matcher.replaceAll(".*");
//python
import re
pattern = re.sub('''\{\d+\}''', '''.*''', string)
在项目中,正则表达式是要自动生成的。比如要把You should modify visibility of class or methods using getDeclaredConstructors(), getDeclaredConstructor(Class[]), setAccessible() or PrivilegedAction.
转化为正则表达式。java里面,我们需要把(
替换为\\(
、)
替换为\\)
、[
替换为\\[
、]
替换为\\]
、.
替换为\\.
,否则生成的正则表达式会有语法错误。(它们在正则表达式中都有特殊使用,也有固定使用格式,所以需要转义。)
你可以用n个replaceAll去实现,而使用正则表达式则就优雅的多。
//java
public static void main(String... args) {
String input = "You should modify visibility of class or methods using getDeclaredConstructors(), getDeclaredConstructor(Class[]), setAccessible() or PrivilegedAction.";
Pattern p = Pattern.compile("\\(|\\)|\\[|\\]|\\.");
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String rep = "\\\\" + m.group(0);
m.appendReplacement(sb, rep);
}
m.appendTail(sb);
System.out.println(sb);
}
`You should modify visibility of class or methods using getDeclaredConstructors\(\), getDeclaredConstructor\(Class\[\]\), setAccessible\(\) or PrivilegedAction\.
`
//python
import re
pattern = re.sub('''[\[\]\.]''', lambda m: '''\\%s''' % m.group(0), input)