簡體   English   中英

Java replaceAll()和split()異常

[英]Java replaceAll() & split() irregularities

我知道,我知道,現在我有兩個問題,但這里的正則表達式意味着我不必編寫兩個復雜的循環。 取而代之的是,我有一個僅能理解的正則表達式,而且我將受雇於yonks。

我有一個字符串,例如stack.overflow.questions[0].answer[1].postDate ,我需要獲取[0]和[1],最好是在數組中。 “簡單!” 我的神經元大叫,只需在輸入字符串上使用正則表達式和split方法; 所以我想出了這個:

String[] tokens = input.split("[^\\[\\d\\]]");

產生了以下內容:

[, , , , , , , , , , , , , , , , [0], , , , , , , [1]]

噢親愛的。 因此,我想,“在這種情況下replaceAll做什么?”:

String onlyArrayIndexes = input.replaceAll("[^\\[\\d\\]]", "");

產生了:

[0][1]

為什么這樣? 我正在尋找一個包含兩個元素的字符串數組,其中第一個元素包含“ [0]”,第二個元素包含“ [1]”。 為什么不拆分這里工作,當時的Javadoc聲明,它們都使用模式類為每的Javadoc

總而言之,我有兩個問題: 為什么split()調用會產生帶有看似隨機的空格字符的大數組, 我是否認為replaceAll有效,因為正則表達式會替換所有不匹配“ [”,數字和“]的字符“? 我想念的是什么意思,我希望他們產生相似的輸出(可以的是三,請不要對此回答“線索”!)。

從我可以看到split確實有效的角度來看,它為您提供了一個數組,用於保存每個匹配項的字符串拆分,該字符串不是一組中間帶有數字的括號。

至於replaceAll我認為您的假設是正確的。 它將刪除您不想要的所有內容(將匹配項替換為"" )。

API文檔中

圍繞給定正則表達式的匹配項拆分此字符串。

該方法的工作方式就像通過調用具有給定表達式且限制參數為零的二參數拆分方法。 因此,結尾的空字符串不包括在結果數組中。

例如,字符串“ boo:and:foo”通過這些表達式產生以下結果:

 Regex Result : { "boo", "and", "foo" } o { "b", "", ":and:f" } 

這不是您問題的直接答案,但是我想向您展示一個適合您需求的出色API。

從Google Guava中查看Splitter

因此,對於您的示例,您將像這樣使用它:

Iterable<String> tokens = Splitter.onPattern("[^\\[\\d\\]]").omitEmptyStrings().trimResults().split(input);

//Now you get back an Iterable which you can iterate over. Much better than an Array.
for(String s : tokens) {
   System.out.println(s);
}

打印:
0
1

split在由您提供的正則表達式定義的邊界上進行split ,因此,獲得很多條目並不令人驚訝-字符串中幾乎所有字符都與您的regex匹配,因此,根據定義,是應該進行拆分的邊界。

replaceAll 您提供的替換替換正則表達式的匹配項,在您的情況下為空白字符串。

如果您嘗試獲取01 ,那么這是一個瑣碎的循環:

String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile("\\[(\\d+)\\]");
Matcher m = pat.matcher(text);
List<String> results = new ArrayList<String>();
while (m.find()) {
    results.add(m.group(1)); // Or just .group() if you want the [] as well
}
String[] tokens = results.toArray(new String[0]);

或者,如果總是恰好是其中兩個:

String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile(".*\\[(\\d+)\\].*\\[(\\d+)\\].*");
Matcher m = pat.matcher(text);
m.find();
String[] tokens = new String[2];
tokens[0] = m.group(1);
tokens[1] = m.group(2);

問題在於,這里的split操作是錯誤的。

在ruby中,我告訴你string.scan(/\\[\\d+\\]/) ,它將為您提供數組["[0]","[1]"]

Java沒有等效的單方法,但是我們可以編寫以下scan方法:

public List<String> scan(String string, String regex){
   List<String> list = new ArrayList<String>();
   Pattern pattern = Pattern.compile(regex);
   Matcher matcher = pattern.matcher(string);
   while(matcher.find()) {
      list.add(matcher.group());
   }
   return retval;
}

我們可以將其稱為scan(string,"\\\\[\\\\d+\\\\]")

等效的Scala代碼為:

"""\[\d+\]""".r findAllIn string

暫無
暫無

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

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