1 package com.yyq;
2
3 import java.io.BufferedReader;
4 import java.io.FileNotFoundException;
5 import java.io.FileReader;
6 import java.util.Arrays;
7 import java.util.TreeSet;
8 import java.util.regex.*;
9 /*
10 * 重要的,必须掌握的 校验。
11 * 对邮件地址的校验。。
12 * 网页爬虫(蜘蛛)
13 *
14 */
15 /*
16 * 正则表达式的功能。
17 * 1.匹配:matches() 真假
18 * 2.切割:split() 切割后的
19 * 3.替换:replace replaceAll() 替换后的
20 * 4.获取: 将字符串中的符合规则的字串取出
21 * 1, 将正则表达是封装成对象。
22 * 2, 让正则对象和要操作的字符串相关联
23 * 3, 通过引擎对符合规则的字串进行操作,比如取出。
24 * 其实 string类中的matches 方法,用的就是pattern 和Matcher
25 * 对象来完成的,只不过被string方法封装后,用起来较为简单,但是功能却单一。
26 *
27 *
28 * 正则表达式: 符合一定规则的表达式。
29 * 作用:用于专门操作字符串
30 * 特点: 用于一些特定的符号来表示一些代码操作。这样就简化书写。
31 * 学习正则表达式 就是学习符号的使用。
32 * matches 方法: 用规则匹配整个字符串,只要有一次不匹配,返回false
33 好处:简化对字符串的复杂操作
34 弊端:阅读性差
35 */
36 /*
37 * 对QQ号码进行校验,
38 * 要求;5-15 0 不能开头,只能是数字
39 * 具体操作功能: 匹配: string matches 方法
40 * [] 校验的特点: 只校验一个位置上的字符,
41 * [a-zA-Z] 所有字符。
42 * [a-z&&[^m-p]]
43 * [a-z&&[^bc]]
44 * 字符类
45 [abc] a、b 或 c(简单类)
46 [^abc] 任何字符,除了 a、b 或 c(否定)
47 [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
48 [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
49 [a-z&&[def]] d、e 或 f(交集)
50 [a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
51 [a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
52
53 预定义字符类
54 . 任何字符(与行结束符可能匹配也可能不匹配)
55 \d 数字:[0-9]
56 \D 非数字: [^0-9]
57 \s 空白字符:[ \t\n\x0B\f\r]
58 \S 非空白字符:[^\s]
59 \w 单词字符:[a-zA-Z_0-9]
60 \W 非单词字符:[^\w]
61
62 * Greedy 数量词
63 X? X,一次或一次也没有
64 X* X,零次或多次
65 X+ X,一次或多次
66 X{n} X,恰好 n 次
67 X{n,} X,至少 n 次
68 X{n,m} X,至少 n 次,但是不超过 m 次
69 特殊构造(非捕获)
70 (?:X) X,作为非捕获组
71 (?idmsux-idmsux) Nothing,但是将匹配标志i d m s u x on - off
72 (?idmsux-idmsux:X) X,作为带有给定标志 i d m s u x on - off
73 的非捕获组 (?=X) X,通过零宽度的正 lookahead
74 (?!X) X,通过零宽度的负 lookahead
75 (?<=X) X,通过零宽度的正 lookbehind
76 (?<!X) X,通过零宽度的负 lookbehind
77 (?>X) X,作为独立的非捕获组
78 边界匹配器
79 ^ 行的开头
80 $ 行的结尾
81 \b 单词边界
82 \B 非单词边界
83 \A 输入的开头
84 \G 上一个匹配的结尾
85 \Z 输入的结尾,仅用于最后的结束符(如果有的话)
86 \z 输入的结尾
87 */
88
89 public class MyDemo {
90 private static String ss = "1111qqq11111111";
91 public static void main(String[] args) throws Exception {
92 //splitDemo();
93 //String str = "aaaaadddffdfdfsdddfaffqwerqsddddafaf"; // 将叠词替换成#号
94 //replaceAllDemo(str,"(.)\\1+","$1"); // 将多个变成一个, 获取组 使用$符号
95 // 拿前一个第一个组 $1 没有大括号
96 //String str = "wer4564664646ssdffff4646546466dddf46498ddd54"; // 将叠词替换成#号
97 //replaceAllDemo(str,"\\d{5,}","#");
98 //checkMain();
99 getMails();
100 }
101 // 到底用四种功能中的哪一个呢? 或者使用哪几个呢??
102 // 1.匹配:判断对错
103 // 2.替换
104 // 3.切割: 获取规则以外的字串
105 // 4.获取:获取符合规则的字串。
106
107 // 192.068.001.254 102.049.023.013 10.10.10.10 2.2.2.2 8.109.90.30
108 // 将ip 地址进行地址段顺序的排序。
109 // 还按照字符串自然顺序,只要让他们每一段都是3位即可
110 /*
111 * 1. 按照每一段需要的最多的0进行补齐,那么每一段就会至少有三位。
112 * 2. 将每一段只保留三位,这样所有的ip地址都是每一段三位。
113 */
114 // 对邮件地址的校验
115 public static void checkMain(){
116 String mail = "1015604150@qq.com.cn.abc";
117 // 较为精确的匹配。
118 String reg = "[a-zA-Z0-9_]{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
119 //相对不精确的匹配。
120 //reg = "\\w+@\\w(\\.\\w)+";
121 System.out.println(mail.matches(reg));
122 }
123 public static void test_2(){
124 String ip = "192.068.001.254 102.049.023.013 10.10.10.10 2.2.2.2 8.109.90.30";
125
126 ip = ip.replaceAll("(\\d+)", "00$1");
127 ip = ip.replaceAll("0*(\\d{3})", "$1");
128 ip = ip.replaceAll("0*(\\d+)", "$1");
129 String [] arr = ip.split(" +");
130 /*Arrays.sort(arr); // 数组排序。
131 for(String s : arr){
132 System.out.println(s);
133 }*/
134 TreeSet<String> ts = new TreeSet<String>();
135 for(String s:arr){
136 ts.add(s);
137 }
138 for(String s : ts){
139 System.out.println(s);
140 }
141 }
142 public static void test_1(){
143 String str = "我我...........我我要...要要...学学学....编编编.编..程....程";
144 /*
145 * 操作: 替换 将一个字符串编程另一个字符串。
146 * 1.先将点去掉
147 * 2.将重复内容编程单个内容。
148 */
149 str = str.replaceAll("\\.+", "");
150
151 // 去除叠词 (.)\\1+
152 str = str.replaceAll("(.)\\1+", "$1");
153 System.out.println(str);
154 }
155 // 按照叠词进行切割。
156 public static void splitDemo(){
157 //String str = "zhangsan.lisi.wangwu";
158 //String reg = "[ ]+"; // 按照多个空格来进行切割。
159 //String reg = "\\."; // 按照. 进行切割
160 //String str = "C:\\abc\\a.txt";
161 //String reg = "\\\\";
162 String str = "abcaaaaabccdef";
163 String reg = "(.)\\1+"; // 叠词进行切割 (要重用的部分叫做组 使用 () 包含,从1 开始编号。) (.)\\1
164 // 为了可以让规则的结果可以被重用,可以将规则封装成一个捕获组,用()完成,组的出现都有编号,//
165 // 从1开始,想要使用已有的组可以通过\\n 来使用组。
166
167 String [] arr = str.split(reg);
168 for(String s:arr){
169 System.out.println(s);
170 }
171 }
172 public static void checkTel(){
173 //匹配手机号段 15***,13***,18***
174 String str = "18753377360";
175 String regex = "[1][538]\\d{9}";
176 if(str.matches(regex)){
177 System.out.println("手机号正确");
178 }
179 else{
180 System.out.println("手机号错误");
181 }
182 }
183 public static void demo(){
184 String str = "b1111";
185 //该只能校验两个位置。
186 String reg = "[a-zA-Z]\\d+";
187 boolean b = str.matches(reg);
188 System.out.println(b);
189 }
190 public static void checkQQ_2(){
191 String qq = "9188536";
192 String regex = "[1-9]\\d{4,14}";
193 if(qq.matches(regex)){
194 System.out.println("it is ok!!!");
195 }
196 else{
197 System.out.println("youw");
198 }
199 }
200 public static void checkQQ(){
201 String qq = ss;
202 int len = qq.length();
203 System.out.println(qq.length());
204 if(!(len>15 || len<5)){
205 if(!qq.startsWith("0")){
206 try{
207 long l = Long.parseLong(qq);
208 System.out.println("qq:" + l);
209 }
210 catch(NumberFormatException e){
211
212 }
213 /*char[] arr = qq.toCharArray();
214 boolean b = false;
215 for(int x = 0;x<arr.length;x++){
216 if(!(arr[x]>='0' && arr[x]<='9')){
217
218 b = true;
219 break;
220 }
221 }
222 if(!b){
223 System.out.println("qq:"+qq);
224 }
225 else{
226 System.out.println("QQ号中出现了非法字符");
227 }
228
229 */
230 }
231 else{
232 System.out.println("不可以0开头");
233 }
234 }
235 else{
236 System.out.println("密码长度不正确。");
237 }
238 }
239 public static void replaceAllDemo(String str,String reg,String newChar){
240 str = str.replaceAll(reg, newChar);
241 System.out.println(str);
242 }
243
244 public static void getDemo(){
245 String str = "ming tian jiu yao fang jia le";
246 String reg = "\\b[a-zA-Z]{4}\\b";
247 //str = "123456789";
248 //String reg ="[1-9]\\d{4,14}";
249 //1. 将正则表达式封装成对象。
250 Pattern p = Pattern.compile(reg);
251 //2.让正则对象和要作用字符串相关连。 获取匹配器对象。
252 Matcher m = p.matcher(str);
253 //m.find(); // 将规则作用到字符串上,并进行符合规则的查找。
254 //m.find();
255 //System.out.println(m.matches());
256 // group() 方法,用于获取匹配后的结果。
257 // 只有找了,才能去。
258 while(m.find()){
259 System.out.println(m.group());
260 }
261 }
262 // 编写网络爬虫
263 /*
264 * 使用获取功能 使用pattern 和matcher
265 * 爬网页上的
266 */
267 public static void getMails() throws Exception{
268 BufferedReader bufr = new BufferedReader(new FileReader("E:\\myjavaee\\aaa\\mail.txt"));
269 String line = null;
270 //1.编写正则表达式
271 String reg = "[a-zA-Z0-9_]{6,14}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
272 //2.将正则表达式封装成对象
273 Pattern p = Pattern.compile(reg);
274
275 while((line = bufr.readLine())!=null){
276 Matcher m = p.matcher(line);
277 while(m.find()){
278 System.out.println(m.group());
279 }
280 }
281 }
282 }