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
		*/
	}
}