有这样一种模式的文本:
Figure 2a. ****.(a).*******. (b).*********.(c).************.
Figure 3d. (a).*******. (b,c,d).*****. (b).***********.(c).********.(d).********
Figure 1a. ****.(a,b).********.
要求,对于“Figure 2a”,抽取出描述“a”的文本部分,而描述它的文本有三部分构成,
一是:全局共有部分,上例中标红的部分;
二是:局部共有部分,上例中标蓝的部分;
三是:(a).后面的描述部分。
解决思路:
(1)、采用java的正则表达式工具,先将这些模式识别出来:
String regex = "(Figure \\d{1,2}[a-z]{1})|(\\([a-z]{1}(, [a-z])*\\))";
(2)、通过两种数据结构来抽取到所要的文本:
LinkedHashMap:<模式的index, 模式文本>,例如[<0,Figure 2a>, <12, (a)>]
LinkedList: 存储模式的位置index
下面直接上代码:
public static String FindCaption(String candidate){
HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
List<Integer> lc = new LinkedList<Integer>();
LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
StringBuffer sb = new StringBuffer();
String regex = "(Figure \\d{1,2}[a-z]{1})|(\\([a-z]{1}(, [a-z])*\\))";
String r = "[a-z]";
candidate = candidate.replaceAll("<\\w+>[\\w?\\d?]</\\w+>", "").replaceAll("<\\w+>", "").replaceAll("</\\w+>", "");
Pattern p = Pattern.compile(regex);
Pattern p2 = Pattern.compile(r);
Matcher m = p.matcher(candidate);
String val = null;
int base = 0;
while (m.find()){
val = m.group();
hm.put(candidate.indexOf(val), val);
lhs.add(candidate.indexOf(val));
//hm存储匹配到的模式的索引和字符串本身,键值对的方式存储
}
for(int i : lhs){
lc.add(i);
}
if (val == null) {
System.out.println("NO MATCHES: ");
sb.append(candidate.substring(candidate.indexOf("Figure")+9));
}else{
base = hm.values().toArray()[0].toString().length();
//"(Figure \\d{1,2}[a-z]{1})"部分的长度
if(base>8){
//表示有子图
String s = hm.values().toArray()[0].toString().substring(base-1);
//获得该幅图像是系列图像中的第几幅,(a,b,c,d?)
//所有图像的公共部分
if(lc.size()>1){
sb.append(candidate.subSequence(lc.get(0)+base+1, lc.get(1)));
}
Set<String> set = null;
for(Map.Entry<Integer,String> es : hm.entrySet()){
if(es.getValue().toString().startsWith("(")){
set = new HashSet<String>();
Matcher m2 = p2.matcher(es.getValue());
while(m2.find()){
set.add(m2.group());
}
if(set.contains(s)){
//表明不是最后一副
if(lc.indexOf(es.getKey())<lc.size()-1){
sb.append(candidate.subSequence(es.getKey()+es.getValue().length(), lc.get(lc.indexOf(es.getKey())+1)));
}else{
//表明是最后一副
sb.append(candidate.substring(es.getKey()+es.getValue().length()));
}
}
}
}
}
}
return sb.toString().trim();
}