簡體   English   中英

具有模式和匹配器的Java正則表達式

[英]Java Regex with Pattern and Matcher

我正在使用Java中的Pattern和Matcher類,正在閱讀Template文本,並且想要替換:

  1. src =“ scripts / test.js”和src =“ scripts / test.js?Id = $ {Id}”
  2. src =“ Servlet?Template = scripts / test.js”和src =“ Servlet?Id = $ {Id}&Template = scripts / test.js”

我正在使用下面的代碼來執行情況2:

//strTemplateText  is the Template's text
Pattern p2 = Pattern.compile("(?i)(src\\s*=\\s*[\"'])(.*?\\?)");
Matcher m2 = p2.matcher(strTemplateText);
strTemplateText = m2.replaceAll("$1$2Id=" +     CurrentESSession.getAttributeString("Id", "") + "&");

上面的代碼對情況2正確工作。但是如何創建一個將兩個情況1和2結合在一起的正則表達式?

謝謝

您不需要正則表達式。 如果將案例2更改為

Servlet?Template=scripts/test.js&Id=${Id}替換Servlet?Template=scripts/test.js

您需要做的只是檢查源字符串是否包含? 如果未添加,則添加?Id=${Id}否則添加&Id=${Id}

畢竟

if (strTemplateText.contains("?") {
    strTemplateText += "&Id=${Id}";
}
else {
    strTemplateText += "?Id=${Id}";
}

做這份工作。

甚至更短

strTemplate += strTemplateText.contains("?") ? "&Id=${Id}" : "?Id=${Id}";

您的實際問題與您的示例代碼不太匹配。 該示例代碼似乎可以處理更一般的情況,並且它替代了實際的會話ID值,而不是對一個值的引用。 下面的代碼采用示例代碼來更好地指示您真正想要的內容,但是相同的方法可以適應您在問題文本中的要求(甚至使用更簡單的正則表達式)。

話雖如此,我看不到用單個replaceAll()來完成此操作的任何方法,因為兩種情況下的替換文本差別太大。 但是,如果您使用其他方法,則可以一次通過一個正則表達式來完成此操作:

Pattern p2 = Pattern.compile("(src\\s*=\\s*)(['\"])([^?]*?)(\\?.*?)?\\2",
        Pattern.CASE_INSENSITIVE);
Matcher m2 = p2.matcher(strTemplateText);
StringBuffer revisedText = new StringBuffer();

while (m2.find()) {
    // Append the whole match except the closing quote
    m2.appendReplacement(revisedText, "$1$2$3$4");
    // group 4 is the optional query string; null if none was matched
    revisedText.append((m2.group(4) == null) ? '?' : '&');
    revisedText.append("Id=");
    revisedText.append(CurrentESSession.getAttributeString("Id", ""));
    // append a copy of the opening quote
    revisedText.append(m2.group(2));
}
m2.appendTail(revisedText);

strTemplateText = revisedText.toString();

這依賴於BetaRide的觀察,即查詢參數的順序並不重要,盡管相同的通用方法可以滿足將Id作為第一個查詢參數的要求,就像在問題中那樣。 它還會將模式中src屬性的結尾與正確的結束定界符進行匹配,您的模式無法解決該問題(盡管這樣做是為了避免匹配跨越多個src屬性的文本)。

請注意,以上內容均不能阻止添加重復的查詢參數“ Id”; 這與問題中出現的正則表達式一致。 如果要通過上述方法避免這種情況,則在循環中需要解析查詢字符串(如果有),以確定是否已經存在“ Id”參數。

您可以執行以下操作:

//strTemplateText  is the Template's text
String strTemplateText = "src=\"scripts/test.js\"";
strTemplateText = "src=\"Servlet?Template=scripts/test.js\"";

java.util.regex.Pattern p2 = java.util.regex.Pattern.compile("(src\\s*=\\s*[\"'])(.*?)((?:[\\w\\s\\d.\\-\\#]+\\/?)+)(?:[?]?)(.*?\\=.*)*(['\"])");
java.util.regex.Matcher m2 = p2.matcher(strTemplateText);
System.out.println(m2.matches());
strTemplateText = m2.replaceAll("$1$2$3?Id=" + CurrentESSession.getAttributeString("Id", "") + (m2.group(4)==null? "":"&") + "$4$5");
System.out.println(strTemplateText);

它在兩種情況下都適用。

如果您使用的是Java> 1.6; 然后,您可以使用自定義名稱的組捕獲功能來制作正則表達式exp。 更易於閱讀和調試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM