[英]Java Regex with Pattern and Matcher
我正在使用Java中的Pattern和Matcher類,正在閱讀Template文本,並且想要替換:
我正在使用下面的代碼來執行情況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.