正则表达式:
正则表达式是一个String对象的字符序列,该字符序列中具有特殊意义的字符,这些特殊字符称作正则表达式的元字符
常用正则表达式及其意义
在正则表达式中可以用方括号括起来若干字符来表示一个元字符,该元字符代表方括号中的任何一个字符,例如:
[abc];代表a、b、c、中的任何一个
由于"."代表任何一个字符,所以在正则表达式中如果想要使用普通意义的点字符,必须使用[.]或\56表示普通意义的点字符。
正则表达式中可以使用限定修饰符
带限定修饰符模式 | 意义 |
---|---|
x? | x出现0次或1次 |
x* | x出现0次或多次 |
x+ | x出现1次或多次 |
x{n} | x恰好出现n次 |
x{n,} | x恰好出现n次 |
x{n,m} | x出现n次至m次 |
xy | x的后缀是y |
x | y |
基础代码:
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;
public class Test {
public static void main(String[] args) {
String regex="[a-zA-Z|0-9]+";
Scanner scanner=new Scanner(System.in);
String str=scanner.nextLine();
if(str.matches(regex)){
System.out.println(str+"是由英文字母、数字、下划线构成");
}
else
System.out.println(str+"中有非法字符");
}
}
class GetPrice {
public static double givePriceSum(String cost) {
Scanner scanner = new Scanner(cost);
scanner.useDelimiter("[^0123456789.]+");
double sum = 0;
while (scanner.hasNext()) {
try {
double price = scanner.nextDouble();
sum += price;
} catch (InputMismatchException exp) {
String t = scanner.next();
}
}
return sum;
}
}
字符串的替换
String对象调用public String replaceAll(String regex,String replacement)方法返回一个新的String对象,这个新的String对象的字符序列是把当前String对象的字符序列中所有和参数regex匹配的子字符序列,用参数replacement的字符序列替换后得到字符序列
String对象调用replaceAll()方法返回一个新的String对象,但不会改变当前String对象的字符序列。
字符序列的分解:
public String[] split(String regex),String对象调用该方法时,使用参数指定的正则表达式regex作为分隔标记分解出当前String对象的字符序列中的单词,并将分解出的单词存放在String数组中。
但需要注意的是split()方法认为分隔标记的左侧应该是单词,因此如果和当前String对象的字符序列的前缀和regex匹配,那么split方法分解出来的第一个单词是不包含任何字符的字符序列即“”。
StringTokenizer类
和split()方法不同的是,StringTokenizer对象不使用正则表达式作为分隔标记。
StringTokenizer(String s):为String对象s构造一个分析器,使用默认的分割标记,即空格符、换行符、回车符、tab符、进纸符作分隔标记。
StringTokenizer(String s,String delim)参数delim中的任意字符排列被作为分隔标记。
基础代码:
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;
public class Test {
public static void main(String[] args) {
String shoppingReceipt="牛奶:8.5,香蕉 3.6,酱油:2.8";
PriceToken lookPriceMess=new PriceToken();
System.out.println(shoppingReceipt);
double sum=lookPriceMess.getPriceSum(shoppingReceipt);
System.out.printf("购物总价格:%-7.2f",sum);
int amount=lookPriceMess.getGoodsAmount(shoppingReceipt);
double aver=lookPriceMess.getAverPrice(shoppingReceipt);
System.out.printf("\n商品数目:%d,平均价格:%-7.2f",amount,aver);
}
}
class PriceToken {
public double getPriceSum(String shoppingReceipt) {
String regex = "[^(0-9|.)]+";
shoppingReceipt = shoppingReceipt.replaceAll(regex, "#");
StringTokenizer fenxi = new StringTokenizer(shoppingReceipt, "#");
double sum = 0;
while (fenxi.hasMoreTokens()) {
String item = fenxi.nextToken();
double price = Double.parseDouble(item);
sum += price;
}
return sum;
}
public double getAverPrice(String shoppingReceipt) {
double priceSum = getPriceSum(shoppingReceipt);
int goodsAmount = getGoodsAmount(shoppingReceipt);
return priceSum / goodsAmount;
}
public int getGoodsAmount(String shoppingReceipt) {
String regex = "[^(1-9|.)]+";
shoppingReceipt = shoppingReceipt.replaceAll(regex, "#");
StringTokenizer fenxi = new StringTokenizer(shoppingReceipt, "#");
int amount = fenxi.countTokens();
return amount;
}
}
Scanner类:
Scannerd对象可以解析字符序列中的单词。
Scanner可以调用useDelimiter(正则表达式)。
将正则表达式作为分隔标记,如果不指定标记,则默认调用空白符。
Scanner对象调用next()方法以此返回被解析的字符序列中的单词,如果最后一个单词已被next()返回,Scannerd对象调用hasNext()将返回false否则返回true.
对于被解析的数字型单词,可以调用nextInt()nextDouble()方法将数字型单词转化为int或double数据返回。
如果单词不是数字型单词,Scannr对象调用nextInt()或nextDouble()方法将会发生inputMismatchException异常,在处理异常时可以调用next()方法返回非数字化单词。
基础代码:
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;
public class Test {
public static void main(String[] args) {
String cost = "市话76.8元,长途:167.38元,短信 12.68元";
double priceSum = GetPrice.givePriceSum(cost);
System.out.printf("%s\n总价:%.2f元\n", cost, priceSum);
cost = "牛奶:8.5,香蕉 3.6元,酱油:2.8元";
priceSum = GetPrice.givePriceSum(cost);
System.out.printf("%s\n总价:%.2f元\n", cost, priceSum);
}
}
class GetPrice {
public static double givePriceSum(String cost) {
Scanner scanner = new Scanner(cost);
scanner.useDelimiter("[^0123456789.]+");
double sum = 0;
while (scanner.hasNext()) {
try {
double price = scanner.nextDouble();
sum += price;
} catch (InputMismatchException exp) {
String t = scanner.next();
}
}
return sum;
}
}
StringTokenzier和Scanner的区别:
StringTokenzier类把分解出的全部单词都存放到StringTokenzier对象的实体中,,因此,StringTokenzier对象能较快速度获取单词,即StringTokenzier对象的实体占用较多的内存(即用空间换取内存)
Scanner类不把单词存放到Scanner对象实体中,而是仅仅存放怎样获取单词的分隔标记,即Scanner获取单词的速度相对较慢,但节省内存空间(即以速度换取空间
StringTokenzier对象一旦诞生就立刻可以知道单词的数目,既可以用countTokens()返回单词数目,而Scanner不提供这样的方法,因为Scanner类不把单词存放到Scanner对象的实体中,如果想要知道单词的数目,就必须一个一个去或取。