正则表达式:符合一定规则的表达式.
作用:用于专门操作字符串
特点:用于一些特点的符号来表示一些代码的操作,这样的简化书写.
所以学习正则表达式,就是在学习一些特殊符号的应用..
好处:可以简化对字符串的复杂处理
弊端:符号定义越多,正则越长,阅读新越差.
作用:用于专门操作字符串
特点:用于一些特定的符号来表示一些代码的操作,这样就简化书写.
学习正则表达式,就是在学习一些特殊符号的作用,.
好处:可以简化对字符串的复杂操作
弊端:符号定义越多,正则越长,阅读新越差
具体的操作:
1,匹配:String matches方法.用正则表达式匹配整个字符串,只要有一处不匹配,都会返回false;
2,切割:String split()方法,String[]arr
3,替换:String replaceAll(regex,"*")如果regex中有定义组,可以在第二个参数中通过$符号来获取正则表达式已经有的组.
String str = str1.replaceAll("(.)\\1+","$");//获取已经有了的正则表达式.
对该QQ号码进行效验:
条件:要求1-15位之间,不能以0开头. 以下用到非正则表达式:
这种方式使用到了String类中的方法,进行了组合的需求,但是代码过于复杂.
package com.javami.kudyDemo.Regex;
public class RegexDemo
{
public static void main(String[]args)
{
String qq = "9496234567a";
Check_qq(qq);
}
/*
* 第一条件: QQ号码的长度 大于 5 并且小于15
* 第二条件:判断是否为零开头.如果为零开头.转换成long类型.. 如果发生异常.代表转换不成功.那么该数字就是为零开头啦.
*/
private static void Check_qq(String qq)
{
int len = qq.length();//获取QQ的长度
if(len>=5&&len<=15)
{
if(!qq.startsWith("0")) //如果不是零开头的
{
try
{
Long l = Long.parseLong(qq);//如果转换不成功.代表异常出现
System.out.println("qq号码为:"+l);
}catch(NumberFormatException e)
{
System.out.println("出现非法的字符");
}
}else
{
System.out.println("数字不能为开头");
}
}else
{
System.out.println("QQ的长度不够,长度为:"+len);
}
}
}
第二种方法:使用到了正则表达式
System.out.println("\\d"); 在java的语言中,\\ 代表一个..
private static void Check_qq2(String qq)
{
String regex = "[1-9]\\d{4,15}"; //由于java中的\\代表一个\
//表达式:第一个数字 为1-9 \\d至少1+4个,并且少于15个而且是数字的
boolean flog = qq.matches(regex);
System.out.println(flog);
}
匹配:
手机号码只有:
13***
15***
18***
private static void Check_Number(String number)
{
String regex = "1[358]\\d{9}";
boolean flog = number.matches(regex);
System.out.println(flog);
}
切割的用法:
对空格进行分隔
String someName = "张三 李四 王五";
private static void splitDemo(String someName)
{
String regex = " +"; //有一个空格 或者多个空格
String [] arr = someName.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}
String demo = "c:\\abc\\cde";\ 对\\进行切割,注意:\\必须要成对的出现
private static void splitDemo2(String demo)
{
String regex = "\\\\";
String[] arr = demo.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}
对多个点进行分隔:
String demo3 = "zhangsan.....lisi....wangwu";
//以.号进行分隔
private static void splitDemo3(String demo3)
{
String regex = "\\.+"; //一个.或者多个.的地方进行切割
String[]arr = demo3.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}
对叠词进行操作:
String demo4 = "dasdasqqsvcvxcvxddvccxdddccc";
splitDemo4(demo4);
/*
* 按照叠词 完成切割,为了可以让规则的结果重用 可以让规则封装成一个组,用()来完成
* 组的出现编号,
* 从1开始,想要使用自有的组
* \n(n)代表编号的形式来获取
*
*/
private static void splitDemo4(String demo4)
{
String regex = "(.)\\1+";
//.代表叠词.封装成一个组,封装成组是为了重用
//重用第一组的内容,但是这个还是代表了重要第二个叠词的位置的.所以我们要+
//+代表了所有的叠词 ,第三个 ...第四个..
String []arr = demo4.split(regex);
for(String s :arr)
{
System.out.println(s);
}
System.out.println("叠词的操作..");
}
"(.)\\1+"
代表叠词 重用组的内容 + 多个.
package com.javami.kudyDemo.Regex;
public class ReplaceAllDemo
{
public static void main(String[]args)
{
String line = "wer1389980000ty1234564uiod234345675f";
//对5位数字以上的进行切割.有重复的,所以我们需要用到组
ReplaceAllShow(line);
String str1 = "erkktyqqquizzzzzo";//将叠词替换成$. //将重叠的字符替换成单个字母。zzzz->z
RepalceAllShow2(str1);
}
/*
* 将叠词替换成*号
*/
private static void RepalceAllShow2(String str1)
{
String regex = "(.)\\1+";
//叠词,重复第一组.多个叠词
String str = str1.replaceAll(regex,"*");
System.out.println(str);
//String str = str1.replaceAll("(.)\\1+","$");//获取已经有了的正则表达式.
}
/*
* 把叠词替换成#号
*/
private static void ReplaceAllShow(String line)
{
String regex = "\\d{5,}";
//把数字刚好为5个的替换成#号
String strLine = line.replaceAll(regex, "#");
System.out.println(strLine);
}
}
第四个功能:(主要内容.等明天也要复习)
获取:将字符串中的符合规则的字串取出.
操作步骤:
1,将正则表达式封装成对象
2,让正则对象和需要操作的字符串进行关联
3,关联后,获取正则匹配引擎。
4,通过引擎对符合规则的子串进行操作,比如取出.
package com.javami.kudyDemo.Regex;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexDemo2
{
public static void main(String[]args)
{
String str = "ming tian jiu yao fang jia le ,da jia。";
System.out.println(str);
//以单词作为边界 a-z 必须是为4个的 \\b结尾
String regex = "\\b[a-z]{4}\\b";
//将规则封装成对象
Pattern p = Pattern.compile(regex);//封装成对象
//让正则表达式和对作用的字符串进行关联,获取匹配器对象.
Matcher m = p.matcher(str);
//System.out.println(m.matches());//是否匹配.
/*
* 其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的.
* 只不过String 方法封装后,用起来比较简单.但是功能单一.只能是boolean
*/
//m.find();
//System.out.println(m.find());//第一个是啊.
// System.out.println(m.group());//获取到匹配过的内容
//由于匹配过的内容就再也不匹配了,好像一个迭代器
while(m.find())
{
System.out.println(m.group());
System.out.println(m.start()+"......"+m.end());
//可以看出匹配的索引位置 0 - 4算左边,但不算右边
}
}
}
题目的内容,重要...
package com.javami.kudyDemo.Regex;
import java.util.TreeSet;
public class Demo
{
public static void main(String[]args)
{
String mail = "my_kudy@live.cn";
getMail(mail);
Test_1();
Test_2();
}
/*
需求:
将下列字符串转成:我要学编程.
到底用四种功能中的哪一个呢?或者哪几个呢?
思路方式:
1,如果只想知道该字符是否对是错,使用匹配。
2,想要将已有的字符串变成另一个字符串,替换。
3,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。
4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。
*/
private static void Test_1()
{
String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";
//可以把.号替换成""字符串,但是也必须要把重复的内容去掉
String regex = "\\.+";
String line = str.replaceAll(regex, "");
System.out.println(line);
//将重复的内容变成单个,叠词可以有一个.替换成叠词的一个
String regex2 = "(.)\\1+";//注意\\.为.符号 (.)代表叠词的一组 ,复用一组.这一组出现的叠词可以有多个
System.out.println(line.replaceAll(regex2,"$1"));
//$1这个叠词的里面的内容 我 要 学 编 程 叠词里面的第一个内容就是 "我"
//.号是叠词的概念 $1叠词的第一个内容
}
//对邮件进行效验
private static void getMail(String mail)
{
String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9-]+(\\.[a-zA-Z]+)+";//+这个组可以有多个
//a-z和数字前面 可以有多个 @代表一个 ,最后一个的解释,这部分内容可以有一个.但是.只能有一个.这个组还可以有多个
boolean b = mail.matches(regex);
System.out.println(b);
}
/*
192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30
将ip地址进行地址段顺序的排序。
*/
package com.javami.kudyDemo.MyMap;
import java.util.TreeSet;
public class IPDemo
{
public static void main(String[]args)
{
String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
Test_ip(ip);
}
private static void Test_ip(String ip)
{
String regex = "(\\d+)"; //代表-->可以有多个数字的地方,咱们从前面补零
//1.替换,前面补零
ip = ip.replaceAll(regex, "00$1");
System.out.println(ip);
ip = ip.replaceAll("0*(\\d{3})", "$1");
//2.零可以有多个,但是数字最多只有3个的地方替换成 之前$1的内容,而之前$1的内容是 : 比喻: 00192 192
System.out.println(ip);
//注意这个问题!
String arr[] = ip.split(" +");//出现空格或者多个空格的地方分隔
TreeSet<String> ts = new TreeSet<String>();
for(String e : arr)
{
ts.add(e);
}
System.out.println("结果出来啦:");
//通过排序后的结果-->把零去掉
for(String e : ts)
{
String line = e.replaceAll("0*(\\d+)", "$1");
System.out.println(line);
}
/*
* 零可以有多个. 数字可以有多个的地方.假设
* 002.002.002.002
* 第一个条件成立, 0 是有了2个 2只有一个 ,那么就替换成 第一组的内容.第一组里面只有一个2
* 008.109.090.030
*第一个:条件成立 所以为8 第二个 不成立
*第三个:0有一个.后面的有多个 所以为90
*.哈哈.懂了不..yes
*/
}
}
网页的爬虫:
将正则表达式封装成对象.
循环读取一行的内容.将正则表达式与之关联,迭代符合条件的内容.
服务器:
package com.javami.kudyDemo.MyMap;
import java.net.ServerSocket;
import java.net.Socket;
public class RegexDemo3
{
public static void main(String[]args)
{
ServerSocket ss = null;
try
{
ss = new ServerSocket(8888);
while(true)
{
Socket socket = ss.accept();
new Thread(new ThreadServer(socket)).start();
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
多线程实现的:
package com.javami.kudyDemo.MyMap;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ThreadServer implements Runnable
{
Socket socket;
public ThreadServer(Socket socket)
{
this.socket = socket;
}
@Override
public void run()
{
try
{
InputStream ips = socket.getInputStream();
OutputStream ops = socket.getOutputStream();
Thread.sleep(100);
int len = ips.available();
byte[] buf = new byte[len];
ips.read(buf);
String info = new String(buf,0,len);
String firstName = info.substring(0, info.indexOf("\r\n"));
//从第零个获取到换行的地方
String[]arr = firstName.split(" ");
String urlName = arr[1];
File file = new File("src/MyMail"+urlName);
if(!file.isFile())
{
ops.write("404,你懂的".getBytes());
return;
}
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos =
new BufferedOutputStream(ops);//写入流
int l;
while((l=bis.read())!=-1)
{
bos.write(l);
}
bos.flush();
bis.close();
bos.close();
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
try
{
if(socket!=null)
socket.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
网页爬虫功能的实现:
package com.javami.kudyDemo.MyMap;
/*
* 网页爬虫
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo2
{
public static void main(String[]args) throws IOException
{
URL url = new URL("http://127.0.0.1:8888/mail.html");
//获取到一个对象
HttpURLConnection use = (HttpURLConnection)url.openConnection();
//把读取到的数字转换成字符流
BufferedReader br =
new BufferedReader(new InputStreamReader(use.getInputStream()));
String line = null;
String regex = "\\w+@+\\w+(\\.\\w+)+";//代表组里面的内容有多个
Pattern p = Pattern.compile(regex);//将正则表达式封装成对象
//创建正则表达式对象.与之关良..
//循环读取一行内容.用正则表达式去比较..在取里面的符合条件的内容..再循环
while((line=br.readLine())!=null)
{
//读取数据
Matcher matcher = p.matcher(line);//用做匹配器做为比较
//好像一个迭代器
while(matcher.find())
{
String str = matcher.group();//获取到匹配到的内容
System.out.println(str);
}
}
}
}