注:以下实例均来自正则表达式贴吧真实需求。
题目:有一组文件格式是AAA-BBB.mp3
,要求替换成BBB-AAA.mp3
JavaScript答案:
var str="AAA-BBB.mp3";
var pattern=/(\w+?)-(\w+?)\.mp3/g;
var s = str.replace(pattern, '$2-$1.mp3');
console.log(s);
Java答案:
public class Demo {public static void main(String args[]) {String str = "AAA-BBB.mp3";String pattern = "(\\w+?)-(\\w+?)\\.mp3";Pattern regex = Pattern.compile(pattern);Matcher matcher = regex.matcher(str);// $2表示第二个分组中的内容;$1表示第一个分组中的内容String result = matcher.replaceFirst("$2-$1.mp3");System.out.println(result);}
}
题目:要求把json字符串{"a"="123", "b"="12c", "c"="abc"}
改成这样的格式:{a="123", b="12c", c="abc"}
JavaScript答案:
var str = '{"a"="123", "b"="12c", "c"="abc"}';
var pattern = /\"([a-zA-Z]+)\"(?=[=])/g;
var regex = new RegExp(pattern);
var result = str.replace(regex, function (item) {return item.replaceAll('\"', '');
});
console.log(result);
优化:
var str = '{"a"="123", "b"="12c", "c"="abc"}';
var pattern = /\"([a-zA-Z]+)\"(?=[=])/g;
var result = str.replace(pattern, '$1');
console.log(result);
Java答案:
public class Demo {public static void main(String args[]) {String str = "{\"a\"=\"123\", \"b\"=\"12c\", \"c\"=\"abc\"}";String pattern = "\"([a-zA-Z]+)\"(?=[=])";Pattern regex = Pattern.compile(pattern);Matcher matcher = regex.matcher(str);while (matcher.find()) {str = str.replaceAll(matcher.group(), matcher.group().replaceAll("\"", ""));}System.out.println(str);}
}
优化:
public class Demo {public static void main(String args[]) {String str = "{\"a\"=\"123\", \"b\"=\"12c\", \"c\"=\"abc\"}";String pattern = "\"([a-zA-Z]+)\"(?=[=])";Pattern regex = Pattern.compile(pattern);Matcher matcher = regex.matcher(str);String s = matcher.replaceAll("$1");System.out.println(s );}
}
题目:要求数值范围在[1-10000]
之内(并且包含边界)并保留两位小数的正则表达式。
答案:\b([\d]{1,4}|10000)\.[\d]{1,2}\b
解释:可以匹配"1.00 56.96 555.11 10000.34 10001.56 123.345"
中的"1.00"
、"56.96"
、"555.11"
、"10000.34"
。将小数点前面的部分分为两种情况处理:[1-9999]
和10000
,因为10000
只需要出现一次。
题目:要求以from开头,以end或over结尾
答案:^from.*?(end|over)$
解释:开头和结尾用^
和$
符号即可,但(end|over)
表示字符串"end"
或"over"
,表示字符串的或
。
题目:要求匹配文本
测试文本:
<span class=\"pl-c1\">https</span>:<span class=\"pl-c1\">//access.redhat.com/security/cve/cve-2009-0035</span></td>\n </tr>\n <tr>\n <td id=\"L10\" class=\"blob-num js-line-number\" data-line-number=\"10\"/>\n <td id=\"LC10\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-c1\">5050</span>\t<span class=\"pl-c1\">1</span>\t<span class=\"pl-c1\">2019-11-06T19</span>:<span class=\"pl-c1\">15Z</span>\t<span class=\"pl-c1\">CVE-2009-5050</span>\t<span class=\"pl-c1\">konversation \u306b\u304a\u3051\u308b\u5165\u529b\u78ba\u8a8d\u306b\u95a2\u3059\u308b\u8106\u5f31\u6027</span>\t<span class=\"pl-c1\">https</span>:<span class=\"pl-c1\">//bugs.kde.org/show_bug.cgi?id=219985</span>
中的超链接,例如:https://bugs.kde.org/show_bug.cgi?id=219985。
答案:<span class=\\"pl-c1\\">(http[s]?)</span>(:)<span class=\\"pl-c1\\">(.*?)</span>
解释:然后分别使用分组提取前三组就可以拼接成一个完整的超链接,Java代码如下:
public class Test01 {public static void main(String[] args) {String html="<span class=\\\"pl-c1\\\">https</span>:<span class=\\\"pl-c1\\\">//access.redhat.com/security/cve/cve-2009-0035</span></td>\\n </tr>\\n <tr>\\n <td id=\\\"L10\\\" class=\\\"blob-num js-line-number\\\" data-line-number=\\\"10\\\"/>\\n <td id=\\\"LC10\\\" class=\\\"blob-code blob-code-inner js-file-line\\\"><span class=\\\"pl-c1\\\">5050</span>\\t<span class=\\\"pl-c1\\\">1</span>\\t<span class=\\\"pl-c1\\\">2019-11-06T19</span>:<span class=\\\"pl-c1\\\">15Z</span>\\t<span class=\\\"pl-c1\\\">CVE-2009-5050</span>\\t<span class=\\\"pl-c1\\\">konversation \\u306b\\u304a\\u3051\\u308b\\u5165\\u529b\\u78ba\\u8a8d\\u306b\\u95a2\\u3059\\u308b\\u8106\\u5f31\\u6027</span>\\t<span class=\\\"pl-c1\\\">https</span>:<span class=\\\"pl-c1\\\">//bugs.kde.org/show_bug.cgi?id=219985</span>";Pattern pattern = Pattern.compile("<span class=\\\\\"pl-c1\\\\\">(http[s]?)</span>(:)<span class=\\\\\"pl-c1\\\\\">(.*?)</span>");Matcher matcher = pattern.matcher(html);while (matcher.find()) {// https://access.redhat.com/security/cve/cve-2009-0035// https://bugs.kde.org/show_bug.cgi?id=219985System.out.println(matcher.group(1)+matcher.group(2)+matcher.group(3));}}
}
题目:有一段文本[123]+[345].[789]*[111].[222].[333]
,要求取出[345].[789]
和 [111].[222]
。
答案:\[\d+\]\.\[\d+\]
解释:需要注意[
和]
是元字符,必须进行转义。
题目:验证号码长度是9位还是10位,如果是10位则首字母必须是0。
答案:\b0?[\d]{9}\b
解释:文本如123456789 1234567890 0123456789
会匹配第一项和第三项,注意正则表达式中用了边界条件\b
,因为是测试文本是多个字符串,而实际运用中只会有一个字符串,可以去掉边界条件,当然有也不影响。
题目:匹配每个换行符之前最后一个中文符号之后的任意内容。
答案:[^\u4e00-\u9fa5]*(?<!\n)$
解释:注意,使用多行模式,例如匹配
sdfds中文xd123
123中xxx
中的xd123
和xxx
,因为要匹配每一行最后一个中文符号之后换行符之前的任意内容。[\u4e00-\u9fa5]
是用来匹配中文字符。
题目:以518、918、516、916这四组数字结尾的13位数字。
答案:\d{10}(518|918|516|916)
解释:还有更好的结果\d{10}[59]1[68]$
题目:识别字符串中恰好包含三个5的字符串,如a5b5c5
或15552
符合要求,而155535
这种就不符合要求。
答案:^([^5]*5){3}[^5^\s]*$
解释:测试的文本如下:
152535
5556
aa5bb5cc5
56575859
155535
题目:要求匹配的字符串中不包含公司
或厂
或部
。
答案:^(?!.*(公司|厂|部)).+$
或^([^(公司|厂|部)]*)$
解释:测试文本
测试
公司
新东方有限公司
大力加工厂
新闻部
大力出奇迹
公司之力
题目:abababa用aba匹配,实际上出现了三次,写正则表达式来匹配。
答案:(?=aba)
解释:利用断言来实现。
题目:要求匹配一个大于0小于等于24并且最多有两位小数的数字。
答案:^(24(\.0{1,2})?|(1[0-9]|[1-9]|2[0-3])(\.\d{1,2})?|0\.[1-9][0-9]?|0\.0[1-9])$
解释:其实是分为了几种情况来讨论:第一种情况,能匹配24或24.0或24.00,那么正则表达式是24(\.0{1,2})?
;第二种情况,能匹配到0.10-0.99,那么正则表达式是0\.[1-9][0-9]?
;第三种情况,能匹配到0.01到0.09,那么正则表达式是0\.0[1-9]
;第四种情况:能匹配到20.00到23.99,那么正则表达式是2[0-3](\.\d{1,2})?
;第五种情况:能匹配到1.00到9.99,那么正则表达式是[1-9](\.\d{1,2})?
;第六种情况:能匹配到10.00到19.99,那么正则表达式是1[0-9](\.\d{1,2})?
。注意,都考虑到了小数点不存在、小数只存在一位的情况。
测试文本:
12.23
0
0.0
1.5
1.234
14.56
24.00
24.12
24
20.12
0.25
0.5
11
7
12.
0.01
0.50
1.50
题目:找出一段html文本中最后一个<br />
之后的所有内容。
测试文本:
xxxxx<br /><p align="center"></p><p align="center"><br /></p>不管大公司还是小公司,都有可能是一个潜力股。<br />给公司取名给公司加分。<br />所以说公司取名,要重视。
答案:[^>]+$
或<br />(?!.*?<br)(.*?)$
解释:第一个答案要简洁得多;第二个答案用了断言和分组,还麻烦。