2016-02-15 11 views
4

我正在寫一個正則表達式來轉義幾個特殊字符,包括來自輸入的雙引號。當文本用雙引號括起來時,在文本中轉義特殊字符

輸入可以用雙引號括起來,這些不應該被轉義。

實施例輸入的:

"te(st", te(st, te"st 

預期輸出:使用

"te\(st", te\(st, te\"st 

代碼:

String regex = "^\".*\"$"; 
    String value = "\"strin'g\""; 
    Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[()'"\\[\\]*]"); 

    if (Pattern.matches(regex, value)){ 
     String val = value.substring(1, value.length() -1); 
     String replaceAll = SPECIAL_REGEX_CHARS.matcher(val).replaceAll("\\\\$0"); 
     replaceAll = "\""+replaceAll+"\""; 
     System.out.println(replaceAll); 
    }else { 
     String replaceAll = SPECIAL_REGEX_CHARS.matcher(value).replaceAll("\\\\$0"); 
     System.out.println(replaceAll); 
    } 

1 - 如果文本被包含在雙引號檢查。如果是,則轉義文本中用雙引號括起來的特殊字符。

2 - 否則。在文本中轉義特殊字符。

任何可以結合#1和#2的正則表達式?

問候, 阿尼爾

+0

可以使用1個正則表達式完成代碼。不過,這需要一些額外的代碼。 –

+0

第三行不能編譯。 – shmosel

+0

你能請分享正則表達式,使用條件正則表達式嗎?我想嘗試這是更好的方法。不知道我的方法是否是標準方法。 –

回答

0

一個轉義正則表達式的簡單解決方案僅

您可以使用if (s.startsWith("\"") && s.endsWith("\""))檢查一個字符串具有前沿和後",如果是的話,你就可以修剪出前導和尾隨"replaceAll("^\"|\"$", ""),然後使用您的轉義正則表達式逃脫,然後添加"回來。否則,只是逃避你的集合中的角色。

String SPECIAL_REGEX_CHARS = "[()'\"\\[\\]*]"; 
String s = "\"te(st\""; // => "te\(st" 
String result; 
if (s.startsWith("\"") && s.endsWith("\"")) { 
    result = "\"" + s.replaceAll("^\"|\"$", "").replaceAll(SPECIAL_REGEX_CHARS, "\\\\$0") + "\""; 
} 
else { 
    result = s.replaceAll(SPECIAL_REGEX_CHARS, "\\\\$0"); 
} 
System.out.println(result.toString()); 

見另一IDEONE demo

替代解決方案與appendReplacement 「回調」

這裏是我會怎麼做,與一個正則表達式使用交替:

String SPECIAL_REGEX_CHARS = "[()'\"\\[\\]*]"; 
//String s = "\"te(st\""; // => "te\(st" 
//String s = "te(st"; // => te\(st 
String s = "te\"st"; // => te\"st 
StringBuffer result = new StringBuffer(); 
Matcher m = Pattern.compile("(?s)\"(.*)\"|(.*)").matcher(s); 
if (m.matches()) { 
    if (m.group(1) == null) { // we have no quotes around 
     m.appendReplacement(result, m.group(2).replaceAll(SPECIAL_REGEX_CHARS, "\\\\\\\\$0")); 
    } 
    else { 
     m.appendReplacement(result, "\"" + m.group(1).replaceAll(SPECIAL_REGEX_CHARS, "\\\\\\\\$0") + "\""); 
    } 
} 
m.appendTail(result); 
System.out.println(result.toString()); 

IDEONE demo

Mai n分:

  • Matcher#addReplacement()Matcher#appendTail()允許操縱組。
  • 使用正則表達式(?s)\"(.*)\"|(.*)用2個選擇分支:".*"匹配的字符串起始"並用"結束(注意(?s)是DOTALL直列改性劑允許與換行序列匹配的字符串)或.*替代剛剛匹配所有其他的字符串。
  • 如果第一個替代項匹配,我們只需替換第一個捕獲組中的所選特殊字符,然後在兩端添加"
  • 如果第二個選擇是匹配的,只需在整個組2中添加轉義符號。
  • 要替換爲文字反斜槓,您需要在替換模式中使用\\\\\\\\
+0

謝謝,它看起來不錯。更簡化的版本? –

+0

你知道,對於不同的人來說,「簡化」可能意味着不同的事情:)我認爲考慮到你的要求,這已經很簡單瞭如果有什麼不清楚的地方,請詢問 –

+0

我已經添加了一個「更簡單」最小的正則表達式 –

0

你可以使用一個negative lookbehind and lookahead

System.out.println(value.replaceAll("([()'\\[\\]*]|(?<!^)\"(?!$))", "\\\\$0")); 

這基本上等於在說:逃脫字符類[()'\[\]*],或任何"任何不想開始子串之前或之後結束的字符串。

唯一的問題是,無論是否在另一端有相應的報價,前導報價和尾隨報價都將被忽略。如果這是一個問題,您可以鏈接這些替換以避開無與倫比的前導或尾隨報價:

.replaceAll("^\".*[^\"]$", "\\\\$0") 
.replaceAll("(^[^\"].*)(\"$)", "$1\\\\$2") 
+0

「(te \」st「不工作 –

+0

查找方法的問題是這樣,無法檢查輸入是否在字符串的開始*和結尾都有''' –

+0

@ AnilDasari,我得到了''\(te \「st」'。你還期待別的什麼嗎? – shmosel

相關問題