import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
/*
回溯引用允许正则表达式模式引用前面匹配的结果
使用的方法是:将需要回溯引用的内容用 ( 和 ) 括起来,当使用的时候,用 \ 加第几个表达式
从1开始,\0表示整个正则表达式
比如:\s+(\w+)\s+\1 这里的意思就是匹配出重复的单词也就是 \w+ 对应的内容的重复出现
*/
public class BackMatch1 {
public static void main(String[] args) {
try{
BufferedReader bf = new BufferedReader(
new FileReader("E:/java/正则表达式练习/RegularExpression/backmatch.txt"));
StringBuffer strbuf = new StringBuffer("");
String str = "";
while ((str = bf.readLine()) != null){
strbuf.append(str);
}
System.out.println(strbuf);
//查找所有的 <h> 标签
// <[Hh][1-6]>.*?</[Hh][1-6]> 因为 * 是贪婪型的,所以需要添加一个 ? 表示懒加载
Pattern p = Pattern.compile("<[Hh][1-6]>.*?</[Hh][1-6]>");
Matcher m = p.matcher(strbuf);
System.out.println(m.pattern()); // <[Hh][1-6].*</[Hh][1-6]>>
while (m.find()){
System.out.println(m.group());
}
/*
<h1>Welcome to my homepage</h1>
<h2>ColdFusion</h2>
<h2>Wireless</h2>
<h2>This is not valid HTML</h3>
*/
//在这里可以发现,第四个<h2>标签对应的结束的是</h3>显然这不是一个合法的内容,也就是说我的
//正则表达式匹配到了开始和结束标签不同的内容
System.out.println();
//采用回溯引用的方法
// <[Hh]([1-6])>.*?</[Hh]\1>
p = Pattern.compile("<[Hh]([1-6])>.*?</[Hh]\\1>");
m = p.matcher(strbuf);
while (m.find()){
System.out.println(m.group());
}
/*
<h1>Welcome to my homepage</h1>
<h2>ColdFusion</h2>
<h2>Wireless</h2>
*/
System.out.println();
}
catch (IOException ex){
ex.printStackTrace();
}
String str2 = "This is a block of the text, several words hewew are are repeated, and and they shout not be.";
//匹配出连续重复的单词 \s+(\w+)\s\1
Pattern p2 = Pattern.compile("\\s+(\\w+)\\s\\1");
Matcher m2 = p2.matcher(str2);
System.out.println(m2.pattern()); // \s(\w+)\s\1
while (m2.find()){
System.out.println(m2.group());
}
/*
are are
and and
*/
}
}
RegularExpression.txt
<body>
<h1>Welcome to my homepage</h1>
Content is divided into two sections:<br>
<h2>ColdFusion</h2>
Infomation about Macromedia ColdFusion.
<h2>Wireless</h2>
Infomation about Bluetooth, 802.11, and more.
<h2>This is not valid HTML</h3>
</body>
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class BackMatchReplace{
public static void main(String[] args){
String str = "Hello, ben@forta.com is my email address.";
// 将里面的网址替换成一个超链接,也就是放在<A>标签内
// (\w+[\w.]*@[\w.]+\.\w+)
// <A HREF=\"mailto:$1\">$1</A>
Pattern p = Pattern.compile("(\\w+[\\w.]*@[\\w.]+\\.\\w+)");
Matcher m = p.matcher(str);
if (m.find()){
String strcha = m.replaceAll("<A HREF=\"mailto:$1\">$1</A>");
System.out.println(strcha);
// Hello, <A HREF="mailto:ben@forta.com">ben@forta.com</A> is my email address.
}
String str2 = "313-555-1234\n 248-555-9999\n 810-555-9000\n";
//将每个电话号码给成(123) 456-7890 的形式
// (\d{3})(-)(\d{3})(-)(\d{4})
// ($1) $3 - $5
p = Pattern.compile("(\\d{3})(-)(\\d{3})(-)(\\d{4})");
m = p.matcher(str2);
if (m.find()){
String strcha = m.replaceAll("($1) $3 - $5");
System.out.println(strcha);
}
/*
(313) 555 - 1234
(248) 555 - 9999
(810) 555 - 9000
*/
}
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
?= 向前查找 指定一个必须匹配但不在结果中返回的模式,只要找到后面指定的内容就可以,
但是不会输出它,也就是不消费它
?<= 向后查找
向前查找和向后查找匹配本身其实是有返回结果,但是这个结果的字节长度永远是 0 而已(zero-width 零宽度)
*/
public class LookBeforeBehind1{
public static void main(String[] args){
String str = "<head> <title> Ben Forta's Homepage</title> </head>";
// 查找出 <title> 标签里面的内容
// <[Tt][Ii][Tt][Ll][Ee]>.*<[Tt][Ii][Tt][Ll][Ee]>
Pattern p = Pattern.compile("<[Tt][Ii][Tt][Ll][Ee]>.*?</[Tt][Ii][Tt][Ll][Ee]>");
Matcher m = p.matcher(str);
System.out.println(m.pattern());
while (m.find()){
System.out.println(m.group());
}
//<title> Ben Forta's Homepage</title>
//匹配出的内容虽然没有错,但是里面的 <head> 标签名并不是想要的
System.out.println();
// (?<=\<[Tt][Ii][Tt][Ll][Ee]>).*?(?=\</[Tt][Ii][Tt][Ll][Ee]>)
// 向后查找 以title为开始,向前查找 以title为结束
p = Pattern.compile("(?<=\\<[Tt][Ii][Tt][Ll][Ee]>).*?(?=\\</[Tt][Ii][Tt][Ll][Ee]>)");
m = p.matcher(str);
while (m.find()){
System.out.println(m.group());
}
//Ben Forta's Homepage
System.out.println();
String str2 = "http://www.forta.com/\n https://mail.forta.com/\n ftp://ftp.forta.com/\n";
//将字符串里面所有的协议名称匹配出来
// .+(?=:)
p = Pattern.compile(".+(?=:)");
m = p.matcher(str2);
while (m.find()){
System.out.println(m.group());
}
/*
http
https
ftp
*/
System.out.println();
String str3 = "ABC01: $23.45 HGG42: $5.31 CFMX1: $899.00 XTC99: $69.96 Total items found: 4";
//将所有的金额查找出来
// \$\d+\.\d{2}
p = Pattern.compile("\\$\\d+\\.\\d{2}");
m = p.matcher(str3);
while (m.find()){
System.out.println(m.group());
}
/*
$23.45
$5.31
$899.00
$69.96
*/
//金额前面都是以 $ 开头的,所以一定要使用 $ 进行匹配,但是匹配的结果中不希望出现 $ 符号
System.out.println();
// (?<=\$)\d+\.\d{2}
p = Pattern.compile("(?<=\\$)\\d+\\.\\d{2}");
m = p.matcher(str3);
while (m.find()){
System.out.println(m.group());
}
/*
23.45
5.31
899.00
69.96
*/
}
}
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/*
(?!) 负向前查找 向前查找取非
(?<!) 负向后查找 向后查找取非
*/
public class LookBeforeBehind2{
public static void main(String[] args){
String str = "I paid $30 for 100 apple, 50 oranges, 60 pears, I saved $5 on this order.";
//匹配出花费的金额
// (?<=\$)\d+
Pattern p = Pattern.compile("(?<=\\$)\\d+");
Matcher m = p.matcher(str);
while (m.find()){
System.out.println(m.group());
}
/*
30
5
*/
System.out.println();
// 同样是上面的内容匹配出所有的购买的数量
// \b(?<!\$)\d+\b
p = Pattern.compile("\\b(?<!\\$)\\d+\\b");
m = p.matcher(str);
while (m.find()){
System.out.println(m.group());
}
/*
100
50
60
*/
}
}