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


[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

将代码合并为一行后得:

MonthSavings
January$100

针对上面一行书写相关的正则表达式, 获取表单中的内容:

((.*?)+?)

这样 $1 就对应着 MonthSavingsJanuary$100 , 接着对匹配后的结果再次进行处理, 使用得正则表达式为:

(.*?)

如此, 匹配得到每一行的内容, 如: $1 = MonthSavings, 接着再使用正则表达式:

(.*?)

就能够得到不同元素, 如:Month, Savings

3.1 Java正则表达式实现简单表单提取

import java.util.regex.*;

public class HtmlTable {
    public static void main(String[] args) {
        // 目标
        String target = "
MonthSavings
January$100
"; // 正则表达式 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