[java] 汇率换算器实现(3)
[java] 汇率换算器实现(3)
[java] 汇率换算器实现(3)
Table of Contents
2 前言
在上一篇文章中, 我们充分了解了正则表达式的使用细则. 那么此处就结合java.util.regex库的使用, 实现HtmlTableParse类, 用于提取网页中table的内容.
3 提取简单表单信息
html表格的示例如下:
<table border="1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
</table>
将代码合并为一行后得:
<table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr></table>
针对上面一行书写相关的正则表达式, 获取表单中的内容:
<table.*?>((<tr>.*?</tr>)+?)</table>
这样 $1 就对应着 <tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr> , 接着对匹配后的结果再次进行处理, 使用得正则表达式为:
<tr>(.*?)</tr>
如此, 匹配得到每一行的内容, 如: $1 = <th>Month</th><th>Savings</th>, 接着再使用正则表达式:
<th>(.*?)</th>
就能够得到不同元素, 如:Month, Savings
3.1 Java正则表达式实现简单表单提取
import java.util.regex.*;
public class HtmlTable {
public static void main(String[] args) {
// 目标
String target = "<table border=\"1\"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr></table>";
// 正则表达式
String regexTable = "<table.*?>((<tr>.*?</tr>)+?)</table>";
String regexRow = "<tr>(.*?)</tr>";
String regexEle = "(?:<th>|<td>)(.*?)(?:</th>|</td>)";
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 上时, 发现最终输出的结果为空. 也就是说一点都没有得到匹配. 这是因为上述的匹配规则过于特殊导致的, 下面给出更为普遍的匹配规则, 能够匹配如下面的格式:
格式:
<TR bgcolor=""></TR>
<TD WIDTH=""></TD>
<TD> <DIV ALIGN="center"><b><font color"">element</font></b></td> 匹配规则:
final static String REGEX_TABLE = "<table.*?>\\s*?((<tr.*?>.*?</tr>)+?)\\s*?</table>";
final static String REGEX_ROW = "<tr.*?>\\s*?(.*?)\\s*?</tr>";
final static String REGEX_ELE = "(?:<th.*?>|<td.*?>)(?:\\s*<.*?>)*(?: )?(.*?)(?: )?(?:\\s*<.*?>)*?\\s*(?:</th>|</td>)";
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 = "<table.*?>\\s*?((<tr.*?>.*?</tr>)+?)\\s*?</table>";
final static String REGEX_ROW = "<tr.*?>\\s*?(.*?)\\s*?</tr>";
final static String REGEX_ELE = "(?:<th.*?>|<td.*?>)(?:\\s*<.*?>)*(?: )?(.*?)(?: )?(?:\\s*<.*?>)*?\\s*(?:</th>|</td>)"; 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
[java] 汇率换算器实现(3)的更多相关文章
- [java] 汇率换算器实现-插曲1-正则表达式(1)
[java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]> [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...
- [java] 汇率换算器实现(2)
[java] 汇率换算器实现(2) // */ // ]]> // */ // ]]> [java] 汇率换算器实现(2) Table of Contents 1 系列文章地址 2 前 ...
- [java] 汇率换算器实现(1)
[java] 汇率换算器实现(1) // */ // ]]> [java] 汇率换算器实现(1) Table of Contents 1 问题描述 2 类设计 3 初步实现 3.1 建立项目 ...
- [java] 更好的书写equals方法-汇率换算器的实现(4)
[java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]> [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...
- [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3
[java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 // */ // ]]> [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 Table of C ...
- [java] jsoup使用简介-汇率换算器实现-插曲2
[java] jsoup使用简介-汇率换算器实现-插曲2 // */ // ]]> [java] jsoup使用简介-汇率换算器实现-插曲2 Table of Contents 1 系列文章 ...
- 【菜鸟学Python】案例一:汇率换算
汇率换算V1.0 案例描述: 设计一个汇率换算器程序,其功能是将外币换算成人民币,或者相反 案例分析: 分析问题:分析问题的计算部分: 确定问题:将问题划分为输入.处理及输出部分: 设计算法:计算部分 ...
- 汇率换算自然语言理解功能JAVA DEMO
>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转 ...
- 万航单位换算器 V1.0 绿色版
软件名称: 万航单位换算器软件语言: 简体中文授权方式: 免费软件运行环境: Win 32位/64位软件大小: 347KB图片预览: 软件简介:万航单位换算器是一个可以随意转换单位的绿色软件,这个软件 ...
随机推荐
- 12G服务器在BIOS中收集阵列卡日志(TTY日志)的方法
如果系统进不去.请参考如下方法收集日志. 请准备个U 盘,容量在8G以下(含8G),否则会识别不到. 图片参考,以描述为准 F2 enter BIOS option--> Enter the ...
- Android(5)— Mono For Android 两个功能型外包
0.前言 距上一篇博文貌似很久了,其中原因种种,归根结底是自己没有坚持好,没有静下心来归纳总结,希望从这一刻起每个月坚持写两篇.(哈哈,突然想起老师说起一句话, 晚上在被窝里悄悄发誓好好学习,第二天涛 ...
- GitHub详解(GitHub for Windows)
GitHub详解 GitHub 是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目.它由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath ...
- 【推荐】【给中高级开发者】构建高性能ASP.NET应用的几点建议
本篇目录 早期阶段就要对应用进行负载测试 使用高性能类库 你的应用是CPU密集还是IO密集的 使用基于Task的异步模型,但要慎重 分发缓存和会话(session)状态 创建Web Gardens 巧 ...
- C#中的线程四(System.Threading.Thread)
C#中的线程四(System.Threading.Thread) 1.最简单的多线程调用 System.Threading.Thread类构造方法接受一个ThreadStart委托,改委托不带参数,无 ...
- Java虚拟机9:Java类加载机制
前言 我们知道我们写的程序经过编译后成为了.class文件,.class文件中描述了类的各种信息,最终都需要加载到虚拟机之后才能运行和使用.而虚拟机如何加载这些.class文件?.class文件的信息 ...
- [安卓] 14、安卓HTTP——POST和GET用法分析
内容简介 本文通过建立一个简单的Servlet服务器来分析安卓上用HTTP和服务器通信的细节,旨在演示C/S模式下服务器端和客户端的工作过程. 目录 part.1 用MyEclipse建立一个简单的s ...
- 据说每个大牛、小牛都应该有自己的库——Event处理
今天抽时间写了一部分Event处理方面的函数愈发的觉得jQuery的优秀,自己前期的想法太粗糙,造成后面这些函数参数很多,操作很很不直观,看样子是要重构的节奏,还好小伙儿伴们安慰,架构都是改出来的.继 ...
- 虚拟化平台cloudstack(2)——安装(上)
vmware workstation安装ubuntu server12.04 这个其实没什么说的了,下软件,安装,一顿下一步,OK. 安装完成后,为ubuntu server 12.04安装桌面. 使 ...
- VS 2008 生成操作中各个选项的差别
近日,在编译C#项目时经常发现有些时候明明代码没错,但就是编译不过,只有选择重新编译或者清理再编译才会不出错,本着求学的态度,搜罗了下VS2008IDE中生成操作的种类以及差别,整理如下: 内容( ...