[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. 如何快速清空项目中的session值

    /清空session //第一种:按照指定的名称清空session //request.getSession().removeAttribute("globle_user"); / ...

  2. android 退出机制

    android sdk 退出机制的研究 有多种, 方法一.用list保存activity实例,然后逐一干掉 上代码: import java.util.LinkedList; import java. ...

  3. NetMq学习--发布订阅(一)

    基于NeqMq 4.0.0-rc5版本发布端: using (var publisher = new PublisherSocket()) { publisher.Bind("tcp://* ...

  4. Ubuntu Server 15.04的安装

    U盘启动工具的制作就跟Windows系统以及Linux各版本的desktop版不同,用的工具也是我第一次见到的“Win32_Disk_Imager”(点击下载) 安装过程请参考:http://www. ...

  5. 一用钟情的VS插件系列总目录(值得收藏)

    关于插件,大家的印象可能很多,比如开发者经常使用的Chrome浏览器的扩展程序,某个软件的一个扩展程序等等.我们使用插件的目的是为了提高我们的某些方面的工作效率或者让我们的软件源(Chrome浏览器等 ...

  6. CSS Font知识整理总结

    1.什么是字体 字体是文字的外在形式,就是文字的风格,是文字的外衣.比如行书.楷书.草书,都是一种字体.同样一个字每个人写起来都会有差异,可以说每个人都有一套潜在的字体库.对于web页面来说,字体就是 ...

  7. 【译】ISupportInitialize的用处

    [译]ISupportInitialize的用处 注:本文是对How ISupportInitialize Can Help的翻译.原文作者编写了Sharpgl,这篇文章是对制作Winform控件过程 ...

  8. 使用FiddlerCore来测试WebAPI

    大家在调试Web相关的API时,经常会用Fiddler来查看相关的请求,以及返回结果.当然你也可以尝试修改或者重复你的请求信息.本文主要介绍如何使用代码来实现fiddler的功能. Fiddler C ...

  9. js笔记——js数据类型转换

    以下内容摘录自阮一峰的<语法概述 -- JavaScript 标准参考教程(alpha)>章节『数据类型转换』,以做备忘.更多内容请查看原文. JavaScript是一种动态类型语言,变量 ...

  10. PHP面向对象之魔术方法复习

    魔术方法复习 2014-9-2 10:08:00 NotePad++ By jiancaigege 飞鸿影~========================= 1.__construct() 构造方法 ...