前言:
- IDEA编辑百度翻译API的Demo时最好用GBK编码,不然可能会出现奇奇怪怪的BUG.
- 你问1.1去哪了?去找我在XX群发的Word啊,以后我有空(咕咕咕)修订一下再移植到CSDN上。
- 看完本节,你应该知道了:
-
正则表达式在Java中的简单应用
-
在Java中简单的将Unicode字符转中文
请按需查看
正则表达式截取和Unicode字符转中文:
正则表达式是什么
对正则表达式还没有了解过的同学请点击下面这个链接去了解一下吧,这里我就不重复造轮子了。只需要有基本的了解即可。
在Java中使用正则表达式
实现方法
在Java中实现正则表达式需要使用到两个类:
- Pattern
- Matcher
具体的实现例子如下
//需要处理的字符串。
String string = "姓名:王二狗,手机:17688888114。";
//匹配规则。
String tel = "\\w+";
//Pattern类将正则表达式编译,创建一个正则表达式或者说匹配方式,并用对象表示。
Pattern pattern = Pattern.compile(tel);
//Matcher类则是是使用Pattern对象来进行一系列的匹配操作的类。
Matcher matcher = pattern.matcher(string);
//Matcher类的find方法:如果匹配到符合规则的字符串则返回true。
if(matcher.find()){
//Matcher类的group方法:取出匹配的字符串
System.out.println(matcher.group());
}
控制台输出的结果
17688888114
Regex Tester 插件
如果你使用的是IDEA,我强烈推荐你添加 Regex Tester 插件,这是一个正则表达式的调试插件。有了这个插件,就可以很方便的写出和调整正则表达式。
常用方法
这里我也不重复造轮子了,直接给你们我参考和学习的那篇博客
我认为必须知道Matcher类的方法有
- find
- group
- replaceAll
截取翻译结果
匹配翻译结果
说了这么多知识点,就来实操一遍吧!
首先,我们看翻译API返回给我们的结果:
{“from”:“zh”,“to”:“en”,“trans_result”:[{“src”:"\u9ad8\u5ea6600\u7c73",“dst”:“Height 600 meters”}]}
我们只需要匹配 Height 600 meters
这个时候就需要用到正则表达式中的零宽断言了
代码 | 说明 |
---|---|
(?=exp) | 匹配exp前面的位置。也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp |
(?<=exp) | 匹配exp后面的位置。也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。 |
(?!exp) | 匹配后面跟的不是exp的位置。也叫零宽度负预测先行断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式exp。 |
(?<!exp) | 匹配前面不是exp的位置。也叫零宽度负回顾后发断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式 |
更多语法: 关于正则表达式中的零宽断言
利用零宽断言,对于翻译结果的正则表达式可以写成
(?<=t":").*(?="})
//但是本着匹配内容尽量穷尽的原则,应该写成下面这样会更好一点
(?<=","dst":").*(?=.{4,})
自己动手去试试看吧!
截取结果
匹配完翻译结果之后就要截取出来
/**
@param in传入翻译结果
*/
private static void process(String in) {
String dst = "(?<=\",\"dst\":\").*(?=.{4,})";
Pattern pattern = Pattern.compile(dst);
Matcher matcher = pattern.matcher(in);
if (matcher.find()) {
System.out.println(matcher.group());
}
}
由于上面已经介绍过用法了,这里就不多说了,只提一点,matcher.find()最好放在 if 中,不然遇到匹配不到的情况,程序就会崩溃终止。
代码如下:
private static void process(String in) {
String in = "1234";
String dst = "(?<=\",\"dst\":\").*(?=.{4,})";
Matcher matcher = Pattern.compile(dst).matcher(in);
matcher.find();
System.out.println(matcher.group());
}
控制台:
Exception in thread “main” java.lang.IllegalStateException: No match found
at java.util.regex.Matcher.group(Matcher.java:536)
at java.util.regex.Matcher.group(Matcher.java:496)
at Main.process(Main.java:29)
at Main.main(Main.java:21)
Main的完整代码(想运行的请下载Demo):
import com.baidu.translate.demo.TransApi;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
// 在平台申请的APP_ID 详见 http://api.fanyi.baidu.com/api/trans/product/desktop?req=developer
private static final String APP_ID = "请输入你自己的";
private static final String SECURITY_KEY = "请输入你自己的";
public static void main(String[] args) {
TransApi api = new TransApi(APP_ID, SECURITY_KEY);
String query = "高度600米";
String result = api.getTransResult(query, "auto", "en");
System.out.println(result);
System.out.println("翻译结果: "+process(result));
}
private static String process(String in) {
String dst = "(?<=\",\"dst\":\").*(?=.{4,})";
Matcher matcher = Pattern.compile(dst).matcher(in);
matcher.find();
return matcher.group();
}
}
虽然现在可以截取翻译内容了,但是如果翻译是中文得从Unicode转中文,又是另一种情况了,还有错误抛出、多行输出。这些都将在补充篇用GSON轻轻松松解决。
这里先贴出我之前用正则表达式解决的方法,解决了Unicode转中文,错误抛出,但是多行输入还没解决。
截取翻译结果/异常抛出。
public static String process(String input) {
String result;
String dst = "(?<=t\":\").*?" + "(?=\"\\}]\\})";
Matcher dstMatcher = Pattern.compile(dst).matcher(input);
if (dstMatcher.find()) {
result = dstMatcher.group();
return unicodeToCn(result);
} else {
String error = "(?<=\":\").*?(?=\")";
Matcher errorMatcher = Pattern.compile(error).matcher(input);
String str[] = new String[2];
for (int i = 0; errorMatcher.find(); i++) {
str[i] = errorMatcher.group();
}
result = "错误代码:" + str[0] + "\n错误信息:" + str[1] + "请将错误信息提交至开发者";
}
return result;
}
Unicode转中文:
private static String unicodeToCn(String unicodeString) {
String unicodeCompile = "(?<=\\\\u).{4}?";
Matcher matcher = Pattern.compile(unicodeCompile).matcher(unicodeString);
for (String unicodeChar; matcher.find(); ) {
unicodeChar = matcher.group();
unicodeString = unicodeString.replace("\\u" + unicodeChar,
String.valueOf((char) Integer.valueOf(unicodeChar, 16).intValue()));
}
return unicodeString;
}