2

我正在读取一个带有大量标签的输入 HTML 文件,例如:

<h2 id="head-3d7e87e90500d3645e1f578a2b0fd6b4f7bd4ccf">

head-3d7e87e90500d3645e1f578a2b0fd6b4f7bd4ccf是一些随机值。

例如,我在 ArrayList 中进行了所有必要的替换以使它们看起来像

<h2 id="correctAnchor"> 

但是我在 HTML 上遍历ArrayList& (解析为字符串),但它总是替换最后一个值:

    for (String temp2 : myAnchorLinks) {
        Pattern h2Pattern = Pattern.compile("<h2.*?>");
        Matcher h2Matcher = h2Pattern.matcher(replaceAllTags);
        if (h2Matcher.find()){
            replaceAllTags = replaceAllTags.replace("<h2 id=.*?>", "<h2 id="+temp2+">");        
        }

     }

有什么想法我做错了什么还是有更好的方法?

“什么是维基?

我不能发布所有的 HTML,但它看起来像:

ArrayList = {#blah1, #blah2, #blah3};

4

5 回答 5

2

您的第一个也是最严重的错误是使用replace()而不是replaceFirst().

replace()替换纯文本(不是正则表达式)
replaceAll()replaceFirst()使用正则表达式查找要替换的匹配项

尝试这个:

replaceAllTags = replaceAllTags.replaceFirst("<h2 id=.*?>", "<h2 id="+temp2+">");        
于 2013-09-18T14:52:41.387 回答
2
Map< String, String > replacements = new hashMap<>();
fillReplacements( replacements ); // Create associations between old and new IDs
// maybe from a properties file
for( map.Entry< String, String > e : replacements.entries()) {
   htmlSource = htmlSource.replaceAll( e.getKey(), e.getValue());
}
于 2013-09-18T14:49:06.807 回答
1

如果你有一个Matcher你应该使用它而不是使用在幕后String创建一个新的方法。Matcher

Pattern h2Pattern = Pattern.compile("<h2.*?>");
Matcher h2Matcher = h2Pattern.matcher("");
for (String temp2 : myAnchorLinks) {
    h2Pattern.reset(replaceAllTags);
    replaceAllTags = h2Matcher.replaceAll("<h2 id="+temp2+">");
}

更新:我想,现在我知道你在做什么:

Pattern h2Pattern = Pattern.compile("<h2.*?>");
Matcher m=p.matcher(replaceAllTags);
StringBuffer sb=new StringBuffer();
for(Iterator<String> it=myAnchorLinks.iterator(); it.hasNext() && m.find(); ) {
  m.appendReplacement(sb, "<h2 id="+it.next()+">");
}
m.appendTail(sb);
replaceAllTags=sb.toString();

String这将从您的列表中为您的模式的每次出现分配另一个。但是,如果列表中的匹配项和元素的数量不匹配,您应该关心该怎么办。在我的示例中,它会停在较小的位置上。

于 2013-09-18T14:51:29.943 回答
0

正则表达式总是尽可能匹配。所以,如果你有一个像这样的字符串

<hello world="this"/> is such a nice <place/>

并且你将它与正则表达式匹配<hello world=.?>'它将返回整个字符串,因为它以“>”结尾 - 而不仅仅是你可能期望的第一部分。

您的正则表达式应该是<h2 id=[^>]*>匹配在“>”处停止。

如果你想测试你的正则表达式,这里有一个很好的正则表达式测试器,它还提供了如何在 Java 中转义正则表达式。

于 2013-09-18T15:00:48.287 回答
0

可能你正在尝试做这样的事情:

// Original String
String HTML="aslasasd <h2 id=\"head-abcdefg\">   <h2 id=\"head-hij5345345345n\">";

// Ids to replace secuentially
String[] ids ={"#id1","#id2"};

// Replace pattern
Pattern pattern = Pattern.compile("<h2[^<>\"']id=\"([^\"]*)\"");
Matcher matcher = pattern.matcher(HTML);
int i = 0;

// Loop for each id that match and replace the ramdom id with the next
// id in the list.
while(matcher.find()){
    HTML = HTML.replace(matcher.group(1),ids[i]); // replace Id
    i++;
    if (i > ids.length){
        break; // No more ids to replace
    }
}

// Replaced String
System.out.println(HTML);
于 2013-09-19T07:19:29.437 回答