簡體   English   中英

正則表達式在Java中匹配未轉義的逗號

[英]Regex matching unescaped commas in Java

問題描述

我試圖使用String類提供的split()方法將a拆分為單獨的字符串。 文檔告訴我它將分割參數的匹配,這是一個正則表達式。 我使用的分隔符是逗號,但逗號也可以轉義。 我使用的轉義字符是正斜杠/(只是為了通過不使用反斜杠來簡化操作,因為這需要在Java和正則表達式中的字符串文字中進行額外的轉義)。

例如,輸入可能是這樣的:

a,b/,b//,c///,//,d///,

輸出應該是:

a
b,b/
c/,/
d/,

因此,字符串應該在每個逗號處拆分,除非該逗號前面有奇數個斜杠(1,3,5,7,...,∞),因為這意味着逗號被轉義。

可能的解決方案

我最初的猜測是將它拆分為:

String[] strings = longString.split("(?<![^/](//)*/),");

但這是不允許的,因為Java不允許無限的后視組。 我可以通過用{0,2000}替換*來將重現限制為,例如,2000:

String[] strings = longString.split("(?<![^/](//){0,2000}/),");

但這仍然會對輸入產生限制。 因此,我決定將這一反復出現在后視組中,並想出了這個:

String[] strings = longString.split("(?<!/)(?:(//)*),");

但是,它的輸出是以下字符串列表:

a
b,b (the final slash is lacking in the output)
c/, (the final slash is lacking in the output)
d/,

為什么在第2和第3個字符串中省略了這些斜杠,我該如何解決它(在Java中)?

您可以使用正面外觀在逗號前面加上偶數個斜杠來實現拆分:

String[] strings = longString.split("(?<=[^/](//){0,999999999}),");

但要顯示所需的輸出,您需要進一步刪除剩余的轉義:

String longString = "a,b/,b//,c///,//,d///,";
String[] strings = longString.split("(?<=[^/](//){0,999999999}),");
for (String s : strings)
    System.out.println(s.replaceAll("/(.)", "$1"));

輸出:

a
b,b/
c/,/
d/,

你很近。 要克服lookbehind錯誤,您可以使用此解決方法:

String[] strings = longString.split("(?<![^/](//){0,99}/),")

如果您不介意使用正則表達式的另一種方法,我建議使用.matcher

Pattern pattern = Pattern.compile("(?:[^,/]+|/.)+");
String test = "a,b/,b//,c///,//,d///,";
Matcher matcher = pattern.matcher(test);
while (matcher.find()) {
    System.out.println(matcher.group().replaceAll("/(.)", "$1"));
}

輸出:

a
b,b/
c/,/
d/,

ideone演示

此方法將匹配除分隔逗號之外的所有內容(反向類型)。 優點是它不依賴於外觀。

我喜歡正則表達式,但在這里手動編寫代碼並不容易,即

boolean escaped = false;
for(int i = 0, len = s.length() ; i < len ; i++){
    switch(s.charAt(i)){
    case "/": escaped = !escaped; break;            
    case ",": 
      if(!escaped){
         //found a segment, do something with it
      }
      //Fallthrough!
    default:
      escaped = false;
    }
}
// handle last segment

暫無
暫無

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

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