怎么做直播视频教学视频网站/临沂网站建设方案服务
正则表达式:
正则表达式:符合一定规则的操作字符串的表达式
特点:将操作字符串的代码封装成特定字符 由特定字符组成正则表达式。这样可以简化代码的书写
所以学习正则表达式,就是在学习一些特殊符号的使用。
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。
常用正则表达式规则
字符
x 字符 x
\\ 反斜线字符
\0n 带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 带有十六进制值 0x 的字符 hh
\uhhhh 带有十六进制值 0x 的字符 hhhh
\t 制表符 ('\u0009')
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
\f 换页符 ('\u000C')
\a 报警 (bell) 符 ('\u0007')
\e 转义符 ('\u001B')
\cx 对应于 x 的控制符
字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z
输入的结尾
正则表达式中具有特定意义的字符注意一定的转义 如果没有在字符串的转义里定义就得经过2次转义。。
正则表达式中.代表所有字符的意思 所有你不想让它代表所有字符的意思的话可以写到一对中括号内如[.] 也可以用转义字符转义 如果要转义的话要用2个转义字符如\\.
\.这样写编译不会通过因为正则表达式是写在字符串内的 字符串检测到子窜里有转义符所有就会先被字符串转义而字符串转义里面没有\. 所有编译器不识别报错。。
\\.先被字符串转义成\. 在经过正则表达式转义 所有在字符串转义里面没有的要经过2次转义 而字符串转义里面已定义的只要被字符串转义就可以了 正则表达式里面可以转义也可以不转义 如\\n和\n 都是可以的
组是正则表达式用来封装部分正则的封装体 就跟函数体里封装的是代码一样 组可以内嵌 就跟类里面还可以封装类部类一样 每个组都有指针 通过指针操作组 指针0表示整个正则表达式 所以组的指针从1开始 在正则表达式内部调用组用\指针 由于要经过字窜转义所以写成\\指针 在参数列表内调用定一个正则表达式的组应该用$指针
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
组零始终代表整个表达式。
正则表达式操作步骤: 当然头前3个功能也可以不完全按照这个来直接操作String或Pattern类也可以 如果是地4个功能或其他功能就要按照这个来了
1.按指定的模式将正则表达式编译封装成正则表达式对象
通过Pattern类的compile方法
static Pattern compile(String regex)
将给定的正则表达式编译到模式中。
static Pattern compile(String regex, int flags)
将给定的正则表达式编译到具有给定标志的模式中。
2. 让正则表达式对象和要操作的字符串序列按模式执行匹配操作创建获取匹配引擎 也可以理解为让正则对象和要操作的字符串相关联,关联后,获取正则匹配引擎。
通过Pattern类的matcher方法
Matcher matcher(CharSequence input)
创建匹配给定输入与此模式的匹配器。
3.通过匹配器引擎对符合规则的子串进行操作,比如取出。
具体操作功能:
1,匹配:用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。
String类
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式。
Pattern类
static boolean matches(String regex,CharSequence input)
编译给定正则表达式并尝试将给定输入与其匹配。
Matcher类
boolean matches()
尝试将整个区域与模式匹配。
String类和Pattern类的matches方法调用的是Matcher类的matches方法 被String 和Pattern的方法封装后,用起来较为简单。但是功能不够多。就如Math类的random方法调用的Random类的nextDoube 它只能直接生产0到1的双精度小数 Random的方法丰富的多可以直接生成整数boolean等其他类型的数
事例:验证qq号是否合法
mport java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
String regex;
String qq="233322232";
regex="[1-9]\\d{4,13}";
checkQQ(qq,regex);
String tel="13986868886";
regex="1[358]\\d{9}";
checkTel(tel,regex);
String mail="adadsfadsf@163.COM";
regex="\\w{6,14}@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//相对精准
regex="\\w{6,14}@\\w+(\\.\\w+)+";//不太精准
checkMail(mail,regex);
2,切割:用规则匹配整个字符串,获取不符合规则的子窜
String类
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串。
Pattern类
String[] split(CharSequence input)
围绕此模式的匹配拆分给定输入序列。
String[] split(CharSequence input, int limit)
围绕此模式的匹配拆分给定输入序列。
举例:
//按照.切割 由于.在正则表达式中代表所有字符所有要转义 而又没在字符串转义里注册所以要用到2个转义符号
String name="zhangsan.lisi.wangwu";
regex="\\."; //或者写成regex=[.];
split(name,regex);
//按照叠词切割
name="erkktyqqquizzzzzo";
regex="(.)\\1+";
split(name,regex);
//按照任意个空格进行切割
name="zhangsan wangwu zhaoliu lisi wangqi ";
regex=" +";
split(name,regex);
//将5位以上的数字替换成$号
String str ="wer1389980000ty1234564uiod234345675f";
regex="\\d{5,}";
String newStr="\\$"; //$要被转义因为在正则表达式中它用来调用组。。
replaceAll(str,regex,newStr);
//将重复出现的叠词替换成单个字母
str= "erkktyqqquizzzzzo";
regex="(.)\\1+";
newStr="$1"; //$通过组指针调用组
replaceAll(str,regex,newStr);
//去掉空格和.在把叠字换成单个的字
textFormat();
//获取符合规则的字串和指针
getDemo();
//ip地址排序
ipOldSort();
ipSort();
//从文件和网上获取Email地址
getEmailForFile();
getEmailForURL();
}
3,替换:用规则匹配整个字符串 按条件用新的子窜替换符合规则的子窜 replacement为新的子窜
String
replaceAll(String regex,String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex,String replacement)
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
String
replaceAll(String replacement)
替换模式与给定替换字符串相匹配的输入序列的每个子序列。
String
replaceFirst(String replacement)
替换模式与给定替换字符串匹配的输入序列的第一个子序列。
*需求:
*将下列字符串转成:我要学编程.
*/
static void textFormat(){
String str = "我我...我 我我...我 要要..要 要...要要...学" +
"学学....学学...编.......编 编...编程..程.程程...程...程";
//可以先把.和空格去掉在把重复的字编程单个的字
String regex="[. ]+";
replaceAll(str,regex, "");
str=str.replaceAll(regex, "");
regex="(.)\\1+";
replaceAll(str,regex,"$1");
}
4、获取:将字符串中符合规则的子串取出
例如:
public static void getDemo(){
String str = "ming tian jiu yao fang jia le ,da jia。";
System.out.println(str);
String regex = "\\b[a-z]{4}\\b";
//将规则封装成对象。
Pattern p = Pattern.compile(regex);
//将正则对象和字符串按模式执行匹配操作获取匹配引擎
Matcher m = p.matcher(str);
//find将规则作用到字符串上,并进行符合规则的子串查找。
//如果这里执行了m.matches(regex);那么指针将从t开始
while(m.find()){
//group用于获取匹配后结果。
System.out.println(m.group());
//start end 用来获取匹配前后指针
System.out.println(m.start()+"...."+m.end());
}
}
以上四种功能到底用四种功能中的哪一个呢?或者哪几个呢?
思路方式:
1,如果只想知道该字符是否对是错,使用匹配。
2,想要将已有的字符串变成另一个字符串,替换。
3,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。
4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。
i
/*
练习:
/**
* 将ip地址进行地址段顺序的排序。
* 这是没用正则表达式的情况
*/
static void ipOldSort(){
String ip="192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
String[] ips=ip.split(" ");
Arrays.sort(ips,new Comparator<String>(){
@Override
public int compare(String s1,String s2){
//.在正则表达式里表示所有字符不想表示所有字符的话就一定记得转义
//比较2个数字字符串的大小不要用compareTo比较 要转换成Integer在比较
String[] tmpS1s=s1.split("[.]");
String[] tmpS2s=s2.split("\\.");
int ret=0;
for(int i=0;i<tmpS1s.length;i++){
ret=Integer.parseInt(tmpS1s[i])-Integer.parseInt(tmpS2s[i]);
if(ret!=0){
break;
}
}
return ret;
}
});
out.println("old ip sort:"+Arrays.toString(ips));
}
static void ipSort(){
String ip="192.168.1.2 11.1.3.4 0.32.32.34 10.2.4.3 2.3.4.2";
//首先把每个IP地址的每个段头前都补2个0 在让每个段都成3位
String regex="(\\d+)";
ip=ip.replaceAll(regex, "00$1");
regex="0*(\\d{3})";
ip=ip.replaceAll(regex, "$1");
//在通过空格切割这个字串
String[] ips=ip.split(" +");
//通过Arrays.sort进行排序
Arrays.sort(ips);
//输出
for(int index=0;index<ips.length;index++){
ips[index]=ips[index].replaceAll("0*(\\d+)","$1");
}
System.out.println("new ip sort:"+Arrays.toString(ips));
}
/**
* 更具文件爬Email
*/
static void getEmailForFile(){
try {
FileInputStream fis=new FileInputStream("g:/mail.txt");
getEmail(fis);
} catch (FileNotFoundException e) {
System.out.println("g:/mail.txt文件不存在或者是目录或权限不够或隐藏等等");
}
}
static void getEmailForURL(){
try {
InputStream in=new URL("http://192.168.1.245:8080/").openStream();
} catch (MalformedURLException e) {
System.out.println("建立连接失败请检查域名端口是否错误");
} catch (IOException e) {
System.out.println("IO错误");
}
}
/**
* 网页爬虫(蜘蛛)
*/
static void getEmail(InputStream in){
StringBuilder sb=new StringBuilder();
byte[] buf=new byte[1024];
try {
for(int len;(len=in.read(buf))!=-1;){
sb.append(new String(buf,0,len));
}
} catch (IOException e) {
System.out.println("IO流读取操作错误");
}finally{
if(in!=null){
try {
in.close();
} catch (IOException e) {
System.out.println("IO输入流关闭错误");
}
}
}
String regex="(\\w)+@\\w+(\\.\\w{2,})+";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(sb.toString());
while(matcher.find()){
System.out.println(matcher.group());
}
}
}