[java] 汇率换算器实现(3)

 

[java] 汇率换算器实现(3)

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*<.*?>)*(?:&nbsp;)?(.*?)(?:&nbsp;)?(?:\\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*<.*?>)*(?:&nbsp;)?(.*?)(?:&nbsp;)?(?:\\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

Validate XHTML 1.0

[java] 汇率换算器实现(3)的更多相关文章

  1. [java] 汇率换算器实现-插曲1-正则表达式(1)

    [java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]>   [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...

  2. [java] 汇率换算器实现(2)

    [java] 汇率换算器实现(2) // */ // ]]> // */ // ]]>   [java] 汇率换算器实现(2) Table of Contents 1 系列文章地址 2 前 ...

  3. [java] 汇率换算器实现(1)

    [java] 汇率换算器实现(1) // */ // ]]>   [java] 汇率换算器实现(1) Table of Contents 1 问题描述 2 类设计 3 初步实现 3.1 建立项目 ...

  4. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  5. [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3

    [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 // */ // ]]>   [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 Table of C ...

  6. [java] jsoup使用简介-汇率换算器实现-插曲2

    [java] jsoup使用简介-汇率换算器实现-插曲2 // */ // ]]>   [java] jsoup使用简介-汇率换算器实现-插曲2 Table of Contents 1 系列文章 ...

  7. 【菜鸟学Python】案例一:汇率换算

    汇率换算V1.0 案例描述: 设计一个汇率换算器程序,其功能是将外币换算成人民币,或者相反 案例分析: 分析问题:分析问题的计算部分: 确定问题:将问题划分为输入.处理及输出部分: 设计算法:计算部分 ...

  8. 汇率换算自然语言理解功能JAVA DEMO

    >>>>>>>>>>>>>>>>>>>>>>>> 欢迎转 ...

  9. 万航单位换算器 V1.0 绿色版

    软件名称: 万航单位换算器软件语言: 简体中文授权方式: 免费软件运行环境: Win 32位/64位软件大小: 347KB图片预览: 软件简介:万航单位换算器是一个可以随意转换单位的绿色软件,这个软件 ...

随机推荐

  1. mysql 数值函数

    可使用常见的算术操作符.注意就 -. +和 *而言, 若两个参数均为正数,则其计算结果的精确度为 BIGINT (64比特),若其中一个参数为无符号整数, 而其它参数也是整数, 则结果为无符号整数.请 ...

  2. No prohects are avaliable for deployment to this server

    没有项目可用于部署到该服务器的项目或者所有项目都已部署到该服务器或没有发现项目 报错的就是这样的信息,网上看了很多解决方案,比如:http://ttov.blog.163.com/blog/stati ...

  3. Version history of VC++, MFC and ATL

    I have tried to assemble together information about the Visual C++ releases, the compiler and the fr ...

  4. OSX 下搭建Asp.Net vNext的开发环境

    开年第一天,按照惯例逛逛各个网站,看看7天有没有什么错过的东西,偶见VS 2015的CPT 6发布了,据说更新ASP.NET,就顺便去官方网站看了看,也忘记在什么地方偶然发现一个叫OmniSharp的 ...

  5. RCP中如何使用代码安装、运行plugins

    其实在google或者http://www.eclipse.org/forums/就能够找到这个问题的答案. 搜索关键字:rcp install plugins\bundles programmati ...

  6. 十进制数转化成二进制后包含一的数量(c++)

    #include <iostream> using namespace std;int func(int x){    int count=0;    while(x){          ...

  7. Gradle与Gatling脚本集成

    Gatling作为次时代的性能测试工具,由于其API简洁明了.性能出众,越来越受欢迎.但是运行Gatling脚本却有诸多不便,其提供的默认方式不是很方便.考虑到Gatling脚本本质上是Scala类, ...

  8. MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能. 基本功能:实现带有进度条的文件上传功 ...

  9. Lucene系列-facet

    1.facet的直观认识 facet:面.切面.方面.个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品.其中品牌 ...

  10. TACACS.Net Group 配置

    Tacacs作为一个验证工具,其网站上资料较少,只有一些缺省配置,并且没有提到如果在应用中与其自带的Group功能做集成, 这里使用免费的windows 版的TACACS.net 作介绍http:// ...