[java] 汇率换算器实现(3)
[java] 汇率换算器实现(3)
Table of Contents
- 1 系列文章地址
- 2 前言
- 3 提取简单表单信息
- 3.1 Java正则表达式实现简单表单提取
- 3.2 重新整理HtmlTable类
- 4 总结
1 系列文章地址
- java 汇率换算器的实现(1)
- java 汇率换算器的实现(2)
- java 汇率换算器实现-插曲1-正则表达式(1)
2 前言
在上一篇文章中, 我们充分了解了正则表达式的使用细则. 那么此处就结合java.util.regex库的使用, 实现HtmlTableParse类, 用于提取网页中table的内容.
3 提取简单表单信息
html表格的示例如下:
| Month |
Savings |
| January |
$100 |
将代码合并为一行后得:
针对上面一行书写相关的正则表达式, 获取表单中的内容:
((.*?
)+?)
这样 $1 就对应着 | Month | Savings |
|---|
| January | $100 |
, 接着对匹配后的结果再次进行处理, 使用得正则表达式为:
(.*?)
如此, 匹配得到每一行的内容, 如: $1 = | Month | Savings | , 接着再使用正则表达式:
| (.*?) |
就能够得到不同元素, 如:Month, Savings
3.1 Java正则表达式实现简单表单提取
import java.util.regex.*;
public class HtmlTable {
public static void main(String[] args) {
// 目标
String target = "";
// 正则表达式
String regexTable = "((.*?
)+?)";
String regexRow = "(.*?)
";
String regexEle = "(?:| | )(.*?)(?:| | )";
Pattern r = Pattern.compile(regexTable);
// 表单的匹配
Matcher mTable = r.matcher(target);
while (mTable.find()) {
String strRow = mTable.group(1);
System.out.println("Row: "+strRow);
// 表单中每一行得匹配
Matcher mRow = Pattern.compile(regexRow).matcher(strRow);
while (mRow.find()) {
String strEle = mRow.group(1);
System.out.println("\tTh or td: " + strEle);
// 每一行中每个元素得匹配
Matcher mEle = Pattern.compile(regexEle).matcher(strEle);
while (mEle.find()) {
String result = mEle.group(1);
System.out.println("\t\tElement: " + result);
}
}
}
}
}
但当上述的程序直接运用到 www.usd-cny.com 上时, 发现最终输出的结果为空. 也就是说一点都没有得到匹配. 这是因为上述的匹配规则过于特殊导致的, 下面给出更为普遍的匹配规则, 能够匹配如下面的格式:
格式:
|
element |
匹配规则:
final static String REGEX_TABLE = "
\\s*?((.*?)+?)\\s*?";
final static String REGEX_ROW = "\\s*?(.*?)\\s*?";
final static String REGEX_ELE = "(?:|)(?:\\s*<.*?>)*(?: )?(.*?)(?: )?(?:\\s*<.*?>)*?\\s*(?:|)";
3.2 重新整理HtmlTable类
package com.cnblogs.grassandmoon;
import java.util.regex.*;
import java.io.*;
public class HtmlTable {
final static String ELEMENT_SEPARATOR = "\001";
final static String ROW_SEPARATOR = "\002";
final static String REGEX_TABLE = "\\s*?((.*?)+?)\\s*?";
final static String REGEX_ROW = "\\s*?(.*?)\\s*?";
final static String REGEX_ELE = "(?:|)(?:\\s*<.*?>)*(?: )?(.*?)(?: )?(?:\\s*<.*?>)*?\\s*(?:|)";
public static String extract(int nStartLine, int nEndLine, BufferedReader br)
throws IOException {
String line;
String target = "";
String elements = "";
int i = 0;
// iStartLine[0] = 78;
// iEndLine[0] = 303;
while ((line = br.readLine()) != null) {
++i;
if (i < nStartLine) continue;
line.trim();
target = target + line;
if (i >= nEndLine) break;
}
// 正则表达式
Pattern r = Pattern.compile(REGEX_TABLE, Pattern.CASE_INSENSITIVE);
// 表单的匹配
Matcher mTable = r.matcher(target);
if (mTable.find()) {
String strRows = mTable.group(1).trim();
// 表单中每一行得匹配
Matcher mRow = Pattern.compile(REGEX_ROW, Pattern.CASE_INSENSITIVE).matcher(strRows);
while (mRow.find()) {
boolean firstEle = true;
String strEle = mRow.group(1).trim();
// System.out.println("\nTh or td: " + strEle);
// 每一行中每个元素得匹配
Matcher mEle = Pattern.compile(REGEX_ELE, Pattern.CASE_INSENSITIVE).matcher(strEle);
if (!elements.equals(""))
elements = elements + ROW_SEPARATOR;
while (mEle.find()) {
String result = mEle.group(1).trim();
if (firstEle)
elements = elements + result;
else
elements = elements + ELEMENT_SEPARATOR + result;
firstEle = false;
// System.out.println("\nElement: " + result);
}
if (!elements.equals("")) {
int len = elements.length();
elements = elements.substring(0, len-2);
}
}
}
return new String(elements);
}
}
4 总结
然后再次对实现代码进行了整理, 完整的代码见:RateExchange @ git
再后续的文中, 将介绍如何使用jsoup从网页中提取相应的信息.
Date: 2014-05-12 Mon
Author: Zhong Xiewei
Org version 7.8.11 with Emacs version 24
Validate XHTML 1.0