网页信息抽取的模板匹配方法(原理)

roki 2009-06-15

先看一段模板配置

<?xml version="1.0" encoding="GBK" ?>
<configuration>


<item name="getGidStr"><![CDATA[<select name=gid >[$gidstr]</select>]]>
</item>

<item name="getGidStr_group"><![CDATA[<option value="[$gid]"[$]>[$groupname]</option>]]>
</item>

</configuration>



以第二条getGidStr_group为例, 我们需要把

<option value="[$gid]"[$]>[$groupname]</option>

转化为Java正则,并且要记录$gid和$groupname这两个变量的位置

,转化的步骤,首先是转义正则元字符

 

    static Pattern REG_PATTERN = Pattern.compile(
            "\\.|\\?|\\*|\\(|\\)|\\[|\\]|\\^|\\+|\\||\\$|\\\\|\\{",
            Pattern.CASE_INSENSITIVE);

 

Matcher regm = REG_PATTERN.matcher(expStr);
        StringBuffer sBuf = new StringBuffer();

        // 转义正则元字符
        while (regm.find()) {
            regm.appendReplacement(sBuf, "\\\\$0");
        }
        regm.appendTail(sBuf);

 

 

 

然后是去匹配模板中的变量

 

public static Pattern VAR_PATTERN = Pattern.compile(
            "\\[(\\$|#)(.*?)(\\((.*?)\\))?\\]", Pattern.CASE_INSENSITIVE);

 

 

 

Matcher matcher = VAR_PATTERN.matcher(exp);

      
        // 找到每一个替换变量
        int last = 0;

        int itemCnt = 0;
        while (matcher.find(last)) {
            last = matcher.end();

            StringBuffer sbuf = new StringBuffer();
            // 匹配到[.+?]的话,记录各个变量的group值, 只能是扁平结构
            if (matcher.groupCount() > 0) {

                String var = matcher.group(2);

                if (StringUtils.isEmpty(var))
                    continue;

                String needle = matcher.group(4);
                if (StringUtils.isEmpty(needle)) {

                    exp = Pattern.compile("\\[\\$" + var + "\\]",
                            Pattern.LITERAL).matcher(exp).replaceAll("(.*?)");

                    exp = Pattern
                            .compile("\\[#" + var + "\\]", Pattern.LITERAL)
                            .matcher(exp).replaceAll("(.*)");
                } else {

                    needle = escapeRegular(needle);

                    exp = Pattern.compile(
                            "\\[\\$" + var + "\\(" + needle + "\\)\\]",
                            Pattern.LITERAL).matcher(exp).replaceAll(
                            "(" + needle + "*?)");

                    exp = Pattern.compile("\\[#" + var + "(" + needle + ")\\]",
                            Pattern.LITERAL).matcher(exp).replaceAll(
                            "(" + needle + "*)");
                }

                itemCnt++;
                // 把占位符替换为正则式,暂时不考虑

                varExp.getVarlist().add(new VarAssign.Var(var, itemCnt));

            }
        }

 

 

整个处理函数 ,返回的是这样一个结构

 

 

public class VarAssign {
	Pattern regexp;
	String 	regexpStr;
	ArrayList<Var> varlist=new ArrayList();
	
	public static class Var{
		String var;//变量
		int ids;//group
		VarAssign subVarAssign; //如果是组模式,则这个变量会有组模式中的子模式的信
		
		
		public Var(String var, int ids,VarAssign varAssign) {
			this.var = var;
			this.ids = ids;
			this.subVarAssign=varAssign;
		}
		
		
		public Var(String var, int ids) {
			this.var = var;
			this.ids = ids;
		}
		public int getIds() {
			return ids;
		}
		public void setIds(int ids) {
			this.ids = ids;
		}
		public String getVar() {
			return var;
		}
		public void setVar(String var) {
			this.var = var;
		}


		public VarAssign getSubVarAssign() {
			return subVarAssign;
		}


		public void setSubVarAssign(VarAssign subVarAssign) {
			this.subVarAssign = subVarAssign;
		}
	}


	
	public String toString(){
		StringBuffer sb=new StringBuffer();
		sb.append("regexp:"+regexp+"\n");
		for(Var v:varlist){
			sb.append(v.getVar()+":"+v.getIds());
		}
		
		return sb.toString();
	}
	
	public Pattern getRegexp() {
		return regexp;
	}
 
	public void setRegexp(Pattern regexp) {
		this.regexp = regexp;
	}
	
	
	public VarAssign() {
	}

	public ArrayList<Var> getVarlist() {
		return varlist;
	}

	public void setVarlist(ArrayList<Var> varlist) {
		this.varlist = varlist;
	}

	public String getRegexpStr() {
		return regexpStr;
	}

	public void setRegexpStr(String regexpStr) {
		this.regexpStr = regexpStr;
	}




}
 

 

 

 

 

 

 

 

Global site tag (gtag.js) - Google Analytics