首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 正則表達式提取並替換 HTML 標籤屬性值:實戰模式與代碼詳解

     編輯:Java 相關知識

在處理富文本、CMS 內容遷移、XSS 防護等場景時,常需從 HTML 中提取特定標籤的特定屬性並進行替換。本文提供一個通用的 repDomain 方法,結合 Pattern/Matcher 實現「指定標籤 → 指定屬性 → 條件替換」的完整邏輯,並解析正則關鍵點。

核心代碼

public static String repDomain(String source, String domain, String element, String attr) {
  // 1. 外層正則:匹配 
  //    [^<>]*?  非貪婪匹配非尖括號字符
  //    \\s      屬性前必有空白
  //    (['\"]?) 捕獲引號類型 (單/雙/無)
  //    (.*?)    非貪婪捕獲屬性值
  //    \\1      反向引用相同引號
  String tagRegex = "<" + element + "[^<>]*?\\s" + attr + "\\s*=\\s*(['\"]?)(.*?)\\1([^<>]*)?>";
  
  Pattern pTag = Pattern.compile(tagRegex, Pattern.CASE_INSENSITIVE);
  Matcher mTag = pTag.matcher(source);
  
  StringBuffer result = new StringBuffer();
  while (mTag.find()) {
    String fullTag = mTag.group();           // 整個標籤
    String quote = mTag.group(1);            // 引號
    String attrValue = mTag.group(2);        // 屬性值
    String suffix = mTag.group(3);           // 剩餘屬性
    
    // 2. 內層條件:只處理包含 "/@tenant" 的值
    if (attrValue.contains("/@tenant")) {
      int idx = attrValue.indexOf("/@tenant");
      String newValue = domain + attrValue.substring(idx + 1); // 替換域名
      // 重構標籤
      String newTag = fullTag.replace(attrValue, newValue);
      mTag.appendReplacement(result, Matcher.quoteReplacement(newTag));
    } else {
      mTag.appendReplacement(result, Matcher.quoteReplacement(fullTag));
    }
  }
  mTag.appendTail(result);
  return result.toString();
}

正則關鍵點解析

片段含義
[^<>]*?非貪婪匹配非尖括號,避免跨標籤匹配
\\s屬性名前必有空白,避免匹配到標籤名一部分
(['\"]?)捕獲組 1:單引號/雙引號/無引號 (HTML5 允許無引號)
(.*?)捕獲組 2:屬性值,非貪婪
\\1反向引用捕獲組 1,確保首尾引號一致
([^<>]*)?捕獲組 3:該標籤剩餘屬性,供重構時保留

使用範例

String html = "<a href=\"/@tenant/user/123\">Link</a> <img src=\"/static/logo.png\"/>";
String newHtml = repDomain(html, "https://newdomain.com", "a", "href");
// 結果: <a href="https://newdomain.com/user/123">Link</a> <img src="/static/logo.png"/>

進階建議與避坑

  1. HTML 用正則解析有風險:巢狀標籤、屬性值含 >、註解、CDATA、Script/Style 內容等會導致誤匹配。生產環境建議用 Jsoup 或 Jericho 解析器。
  2. Jsoup 替代方案:
    Document doc = Jsoup.parse(html);
        for (Element a : doc.select("a[href]")) {
          String href = a.attr("href");
          if (href.contains("/@tenant")) a.attr("href", "https://newdomain.com" + href.substring(href.indexOf("/@tenant")+1));
        }
        return doc.body().html();
  3. 效能優化:Pattern.compile 為重量級操作,靜態常量化複用;大量文本處理考慮 Matcher.replaceAll(Function) (Java 9+)。
  4. 編碼一致性:確保源字串與正則編碼一致 (UTF-8),避免中文屬性值匹配失敗。

總結

本文提供的 repDomain 方法展示了「雙層正則 + StringBuffer 重構」的經典替換模式,適用於結構簡單、格式固定的 HTML 片段處理。面對複雜真實 HTML,**務必改用專業解析器 (Jsoup)**,以確保正確性與安全性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved