转载请申明出处:http://blog.csdn.net/xmxkf
day21 字符编码
06-IO流(转换流的字符编码)
字符编码:
1、 字符流的出现为了方便操作字符,更重要的是加入了编码转换。
2、 通过子类转换流来完成:InputStream OutputStream
3、 在两个对象进行构造是可以加入字符集。
4、 可以加入编码表的流还有PrintStream和PrintWriter,但是这两个流只能打印,不能读取
编码表由来:
计算机只能识别二进制数据,早起由来是电信号;为了方便应用计算机,让它可以识别各个国家的文字,就将各国的文字用数字来表示,并一一对应形成一张表。这就是编码表
常见的编码表:
ASCII: 美国标准信息交换码。用一个字节的7位可以表示;
ISO8859-1: 拉丁码表。欧洲码表。用一个字节的8位表示;
GB2312: 中国的中文编码表;两个字节存储一个文字
GBK: 中国的中文编码表升级,融合了更多的中文文字符号;
Unicode: 国际标准码,融合了多种文字;所有的文字都用两个字节来表示,java语言使用的就是unicode
UTF-8: (unicode升级)最多用三个字节来表示一个字符
…………
了解:
1、我们常用的码表:gbk , utf-8 , iso8859-1
访问服务器时,张三----à编码(gbk)------àTomcat服务器解码(iso8859-1)????---à编码(iso8859-1)----à解码(gbk)张三
2、但是gbk和utf-8不能编码解码,因为都识别中文,用gbk编码的字节数组用utf解码,再用utf编码得到的字节数组不会是以前那个字节数组,所以再用gbk解码得到的字符串不同
import java.io.*;
/**
* 用gbk编码表和utf编码表分别写文件和读取文件。
* 但是用一个表写文件,用另外一个表读取文件,就会乱码
*/
public class EncodeStream
{
public static void main(String[]args)throws IOException
{
writeText();
readText();
}
public static void readText() throws IOException
{
//用gbk编码表读取文件,但是文件使用utf表写的
InputStreamReaderisr =
new InputStreamReader(new FileInputStream("utf.txt"),"gbk");
char[] buf =new char[10];
int len =isr.read(buf);
Strings = new String(buf,0,len);
System.out.println(s); //浣犲ソ,
//为什么?因为utf是一个文字3个字节,gbk一个文字两个字节,
//用gbk编码表读文件上两个文字(6个字节),会读出3个字,乱码
//如果用gbk写数据,utf解析数据,返回??
}
public static void writeText() throws IOException
{
//转换流融合了编码表,按照特定编码表写文件
OutputStreamWriterosw =
newOutputStreamWriter(new FileOutputStream("utf.txt"),"utf-8");
osw.write("你好");
osw.close();
}
}
day21-07-字符编码(编码,解码)
import java.util.Arrays;
/**
*编码:字符串变成字节数组 String->byte[];str.getbytes(charsetName);
*解码:字节数组变成字符串byte[]->String; newString(byte[],charsetNmae);
*/
public class EncodeDemo
{
public static void main(String[] args) throws Exception
{
Strings = "你好";
// byte[] b1 = s.getBytes(); //默认是gbk编码表
byte[] b1 = s.getBytes("GBK"); //[-60, -29, -70, -61]
Strings1 = new String(b1,"GBK"); //s1=你好
Strings2 = new String(b1,"ISO8859-1"); //s2=????
//对s进行iso8859-1编码 [-60, -29, -70, -61]
byte[] b2 =s2.getBytes("ISO8859-1");
Strings3 = new String(b2,"GBK");
System.out.println(Arrays.toString(b2));
}
}
day21-08-字符编码-联通
1、记事本是一个软件,新建一个记事本文件后往里面写入数据,然后保存,记事本会以gbk编码表对字符串进行编码;关闭记事本后再次打开,记事本会对其中存的字节码进行解码并显示出来,但是不一定是按照gbk来解码。
2、但是汉字中有两个特殊的字“联通”,它通过记事本编码后得到四个字节码,分别为11000001 10101010 11001101 10101000 符合utf-8(null字符’\u0000’以及从’\u0080’到’\u07FF’的范围内的字符用两个字节表示)。
所以记事本首先就去用utf-8编码表去解码并显示出来,造成乱码
注意:前面加上字母abc……也一样,因为utf-8也可以用一个字节表示字母
在API中DataInputStream类下面可以查看到utf-8内容
public class LianTong
{
public static void main(String[]args) throws Exception
{
Strings = "联通";
byte[] by = s.getBytes("gbk");
for(byte b : by)
{
//取最后8位&255,得到的就是其中一个字节码
System.out.println(Integer.toBinaryString(b&255));
//11000001 10101010 11001101 10101000
}
}
}
day21-09-练习
需求:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课成绩);并把学生信息和计算出的总分数高低顺序存放在磁盘文件“student.txt”中
1、描述学生对象 2、定义一个可操作学生对象的工具类
分析:1、通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象;
2、因为学生有很多,那么就需要存储,使用到集合。因为要对学生总分排序;所以可使用TreeSet;
3、将集合的信息写入到一个文件中。
//获取键盘录入学生信息,并存放到TreeSet集合中
public static Set
{
BufferedReaderbufr=
new BufferedReader(newInputStreamReader(System.in));
Stringline = null; //用于接收读取的一行数据
Set
if(cmp==null) //不传入比较器,学生排序依据自己实现的compareTo方法
stus= new TreeSet
else //传入比较器
stus= new TreeSet
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
String[]info = line.split(",");
//String name =info[0];
System.out.println(info.length);
Studentstu = new Student(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
Day25 正则表达式
01-正则表达式(特点)
正则表达式:符合一定规则的表达式;
作用:用于专门操作字符串;
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则表达式越长,阅读性越差。
特点:用于一些特定的符号来表示一些代码操作,这样就简化书写。
所以学习正则表达式就是在学习一些特殊字符的使用。
//对qq好进行校验,5~15位,不以0开头,只能是数字
public static void checkQQ()
{
Stringqq = "156655";
//第一位1-9,0-9出现4至14次, 或者[1-9]\\d{4,14}
Stringregex = "[1-9][0-9]{4,14}";
boolean flag =qq.matches(regex);
if(flag)
System.out.println(qq+"…is ok");
else
System.out.println(qq+"…不合法");
}
02-正则表达式(匹配)返回
boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
1、匹配:String matches方法。用规则匹配整个字符串,只要有一处不符合规则,就匹配不成功,返回false。
public static void matcesDemo()
{
Stringstr = "b23a";
// 字符类(字母即可,不分大小写) 预定义字符类\d戴白数字0-9,
//Greedy 数量词X* X,零次或多次
Stringregex = "[a-zA-Z]\\d*";
boolean b =str.matches(regex);
System.out.println(b);
}
//匹配手机号端 13xxx 15xxx 18xxx
public static void checkTel()
{
Stringtel = "13825883688";
StringtelReg = "1[358]\\d{9}";
System.out.println(tel.matches(telReg));
}
03-正则表达式(切割)
String[]split(String regex) 根据给定正则表达式的匹配拆分此字符串。
public static void splitDemo(Stringstr, String reg)
{
String[]arr = str.split(reg);
System.out.println(arr.length);
for(String s : arr)
{
System.out.println(s);
}
}
主方法调用:
splitDemo("zhangsan lisi wangwu"," +");//按一个或多个空格切
splitDemo("zhangsan.lisi.wangwu","\\."); //按'.'切
splitDemo("c:\\abc\\a.txt","\\\\"); //按\\切
splitDemo("erkkasdqqsfdzzo"," +(.)\\1+");//按照叠词完成切割 重复的词 +代表出现多次
组:按照叠词完成切割,为了可以让规则的结果重用,可以将规则封装成一个组。用()完成。组的出现都有编号,从1开始。要想使用已有的组可以通过\n(n就是租的编号)的形式来获取。 ((())())判断几个组数左括号(,判断组的编号也看(。
04-正则表达式(替换)
String replaceAll(String regex,String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
public static voidreplaceAllDemo(String str, String reg, String newStr)
{
str= str.replaceAll(reg, newStr);
System.out.println(str);
}
主方法调用:
String str1 = "wer15645648t123d3465u";
replaceAllDemo(str1,"\\d{5,}","#"); //将字符串中的5个以上数组替换成#
Stringstr2 = "erkkefqqqdvfxxxxm";
replaceAllDemo(str2,"(.)\\1+","&"); //将叠词替换成&
Stringstr3 = "erkkefqqqdvfxxxxm";
replaceAllDemo(str3,"(.)\\1+","$1"); //将重叠字母替换为单个字母,$取第一组
day25-05-正则表达式(获取)
java.util.regex
类 Pattern
正则表达式第四个功能:
获取:将字符串中的符合规则的子串取出。
操作步骤:
1、 将正则表达式封装成对象;
2、 让正则对象和要操作的字符串相关联;
3、 关联后,获取正则匹配引擎;
4、 通过引擎对符合规则的子串进行操作,比如取出。
public static void getDemo()
{
Stringstr = "ming tian jiu yao fang jia le ,da jia。";
System.out.println(str);
Stringreg = "\\b[a-z]{4}\\b"; //单词边界,连续四个字母
Patternp = Pattern.compile(reg); //讲规则封装成对象
//将正则对象和要作用的字符串相关联,获取匹配器对象
Matcherm = p.matcher(str);
//boolean b =m.find(); 尝试查找与该模式匹配的输入序列的下一个子序列
//System.out.println(b);
//System.out.println(m.group());返回由以前匹配操作所匹配的输入子序列
//其实其实,String类中的matches ,replaceAll等方法用的就是Pattern和Matcher对象来完成的
System.out.println("matches:"+m.matches()); //matches是整个匹配 false
while(m.find()) //find()是单个查找,直到找到符合规则子串
{
System.out.println(m.group()); // 返回由以前匹配操作所匹配的输入子序列
System.out.println(m.start()+"…"+m.end());
}
}
其实,String类中的matches ,replaceAll等方法用的就是Pattern和Matcher对象来完成的。
只不过被String封装后,用起来较为简单,但是功能却单一。
day25-06-正则表达式(练习1)
需求:将下列字符串转成:我要学编程
到底用四种功能中的哪一个呢?或者那几个?
思路:
1、 如果只想知道字符串师傅符合规则,使用匹配;
2、 想要将已有的字符串变成另一个字符串,替换;
3、 想要按照自定义的方式将字符串变成多个字符串,切割;获取规则以外的子串;
4、 想要拿到符合需求的字符串子串,获取;获取符合规则的子串。
public static void test_1()
{
Stringstr = "我我..我我...我要....要要..要...学学学.....学编........编编..编程......程";
/*将已有字符串编程另一个字符串,使用替换功能
* 1、先将.去掉
* 2、再将多个重复的内容变成单个内容
*/
str= str.replaceAll("\\.+",""); //将多个点替换为空
System.out.println(str);//我我我我我要要要要学学学学编编编编程程
str= str.replaceAll("(.)\\1+","$1");
System.out.println(str); //我要学编程
}
day25-06-正则表达式(练习2)
一、将IP地址进行地址段顺序排序。
192.68.1.254 102.45.23.14 10.10.10.10 2.2.2.2 2.3.2.2 6.32.105.30
还按照字符串自然顺序,只要让它们每一段都是3位即可。
1、 按照每一段需要的最多的0进行补齐,那么每一段就会至少保证3位。
2、 将每一段只保留3位,这样,所有的IP地址都是每一段3位。
public static void test_2()
{
String IP = "192.68.1.254 102.45.23.14 10.10.10.10 2.2.2.2 2.3.2.2 6.32.105.30";
IP = IP.replaceAll("(\\d+)","00$1");
System.out.println(IP);
IP = IP.replaceAll("0*(\\d{3})","$1");
System.out.println(IP);
String[] arr = IP.split(" +");
TreeSet
for(String s : arr)
{
ts.add(s); //排序
}
for(String s : ts)
{
System.out.println(s.replaceAll("0*(\\d+)","$1")); //去掉前面的0
}
}
二、需求:对邮件地址进行校验
public static void checkMail()
{
String mail = "[email protected]";
String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";//+一次或多次 较为精确的匹配
reg = "\\w+@\\w+(\\.\\w+)+"; //相对不太精确的匹配
//mail.indexOf(@)!=-1;
System.out.println(mail.matches(reg));
}
day25-08-正则表达式(网页爬虫)
获取指定文档中的邮件地址,使用功能Pattern Mather
public static void getMails() throws Exception
{
BufferedReaderbufr = new BufferedReader(new FileReader("mail.txt"));
Stringline = null;
Stringmailreg = "\\w+@\\w+(\\.\\w+)+";
Patternp = Pattern.compile(mailreg);
while((line=bufr.readLine())!=null)
{
Matcherm = p.matcher(line);
while(m.find())
{
System.out.println(m.group());
}
}
}
网页上获取
public static void getMails_2() throws Exception
{
URLurl = new URL("http://127.0.0.1:8080/myweb/mail.html");
URLConnectionconn = url.openConnection(); //获取链接对象
BufferedReaderbufIn =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
Stringline = null;
Stringmailreg = "\\w+@\\w+(\\.\\w+)+";
Patternp = Pattern.compile(mailreg);
while((line=bufIn.readLine())!=null)
{
Matcherm = p.matcher(line);
while(m.find())
{
System.out.println(m.group());
}
}
}