簡體   English   中英

Java - RegEx 匹配器:如何顯示所有結果並防止丟失信息

[英]Java - RegEx matcher: how to show all results and prevent losing information


所以我正在用 JAVA 做一個項目,我正在為正則表達式苦苦掙扎。

我試圖簡化我的問題,否則它會太復雜:
我有字符串(簡化:動物列表,如“動物 1:兔龍龜動物 2:馬海豚動物 3:斑比動物 4:獅子貓狗動物 5:野獸” )。
我現在想要的是字符串結果,其中包含動物,例如一個字段 [Rabbit Dragon Turtle, Horse Dolphin, Bambi, lion cat dog, beast] 在我的問題中,我不知道動物的名字,我只知道 String 的結構,即“Animal 1: XXX Animal 2: XXX ...”,而 XXX 可能是一個長度超過一個單詞的字符串。

所以我嘗試的是:

 String animals = "Animal 1: Rabbit Dragon Turtle Animal 2: Horse Animal 3: Bambi Animal 4: lion Animal 5: beast" Pattern pat = Pattern.compile("Animal (\\\\d)(.*?)Animal (\\\\d)"); //that's what I am searching for Matcher mat = pat.mat(animals); while(matcher.find()) { System.out.println(matcher.group()); }

現在我的問題是,我的輸出看起來像
《動物1:兔龍龜動物2》
《動物3:小鹿斑比動物4》
這意味着,我正在失去“動物 2:馬海豚動物 3”部分等等......

所以也許你可以幫助我並告訴我,我可以如何防止丟失信息。
我閱讀了一些教程並發現,如果匹配器與模式匹配,則匹配器會“跳轉”到字符串的其余部分,並且不會從第一個結果開始搜索另一個結果。

如果你能幫助我,那將是非常好的,因為如果我能解決這個問題,我只需要刪除“動物 1”、“動物 2”、“動物 3”......結果 :)

也很抱歉,如果我的英語不好,我不是本地人(這里是德語)。
非常感謝您提前!
親切的問候
巴斯蒂


更新 *** 在得到 2 個非常有用的答案后,這些答案非常有用,但仍然沒有解決我的問題,我意識到,我過於簡化了我的問題。 所以我嘗試一下:我的“真正”問題:

我的字符串是“<w:t>task 1</w:t> XXX <w:t>task 2</w:t> XXX <w:t>task 3</w:t> XXX <w:t >task 4</w:t>" ,它是一個由 word 文檔組成的 XML 字符串。 現在我必須找到<w:t>task n</w:t> 和 <w:t>task n+1</w:t> 之間寫入的所有 XXX

模式需要是:

Pattern pat = Pattern.compile("Animal \\d+:\\s+(\\w+)\\b");
Matcher matcher = pat.matcher(animals);

while(matcher.find()) { 
     System.out.println(matcher.group(1));
}

也就是說,單詞Animal后跟一個數字序列(最小 1) \\d+:和一個空格序列\\\\s+ (最小 1)分隔

動物名稱作為組#1 (\\w+)\\b\\b表示單詞邊界。

因此,輸出為:

Rabbit
Horse
Bambi
lion
beast

更新:

如果使用 Java 9+,則可以使用Matcher::results()提供的匹配結果流而不是while循環:

pat.matcher(animals) // apply the pattern to the input string `animals`
   .results()        // get Stream<MatchResult>
   .map(match -> match.group(1))  // convert to Stream<String>
   .forEach(System.out::println); // print each string using method reference

輸出與上面相同。

使用正則表達式Animal \\d+: \\w+(?=( Animal \\d+:)?) ,這意味着Animal \\d+: \\w+后跟可選的( Animal \\d+:)

Followed By?=指定,即正向前瞻,可選由?=指定? 在可選字符的末尾。

演示:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        String animals = "Animal 1: Rabbit Animal 2: Horse Animal 3: Bambi Animal 4: lion Animal 5: beast";

        Pattern pat = Pattern.compile("Animal \\d+: \\w+(?=( Animal \\d+:)?)");
        Matcher matcher = pat.matcher(animals);

        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

輸出:

Animal 1: Rabbit
Animal 2: Horse
Animal 3: Bambi
Animal 4: lion
Animal 5: beast

如果您不想在Animal \\d+:名稱之前使用Animal \\d+: caption ,一個簡單的解決方案是將字符串拆分為Animal\\\\s+\\\\d+:\\\\s+ ,這意味着Animal后跟一個或多個空格字符后跟一個或多個數字后跟:后跟一個或多個空白字符。

public class Main {
    public static void main(String[] args) {
        String animals = "Animal 1: Rabbit Dragon Turtle Animal 2: Horse Animal 3: Bambi Animal 4: lion Animal 5: beast";
        String[] arr = animals.split("Animal\\s+\\d+:\\s+");

        for (String s : arr) {
            if (!(s.isBlank() || s.isEmpty()))
                System.out.println(s);
        }
    }
}

輸出:

Rabbit Dragon Turtle 
Horse 
Bambi 
lion 
beast

暫無
暫無

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

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