簡體   English   中英

特殊字符的模式搜索

[英]pattern search with special chars

嗨,我想搜索並獲取類似這樣的復雜字符串中所有特殊字符的索引

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";

我正在嘗試搜索所有這樣的模式|* |_ |= |@*| _| =| @| *| _| =| @| 我嘗試這種模式

public int getIndexOfPat(String s){
    Pattern startPat = Pattern.compile("\\|[\\*_@=]");
    Matcher matcher = pattern.matcher(s);
    return matcher.find() ? matcher.start() : -1;
}

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
int i = getIndexOfPat(textWithSpecialChars);
textWithSpecialChars = textWithSpecialChars.substring(i+2);
//I get error here
i = getIndexOfPat(textWithSpecialChars);
// var i still is the first one value

但這只會得到第一個,即使我使用

除了尋找每個模式匹配的開始之外,您還可以找到所有由特殊字符定界的文本,如下所示:

public List<String> getSpecialTextList(String line) {
    List<String> toRet = new ArrayList<String>();

    Pattern pattern = Pattern.compile("\\|([\\*_@=])((?:.(?!\\|))*)\\1\\|");
    Matcher matcher = pattern.matcher(line);
    while (matcher.find()) {
      toRet.add(matcher.group(2));
    }

    return toRet;
}

然后可以像這樣使用它:

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";
List<String> specialTextList = getSpecialTextList(textWithSpecialChars);
System.out.println(specialTextList); // prints [more, tags]

請注意,這對於諸如|*hello|*there*|*|類的嵌套標簽不起作用。

您的問題是,每次調用getIndexOfPat您都在重新創建Matcher實例(Pattern但重新編譯Pattern在這里不是問題,這只是無效的代碼)。 因此,每次調用find都會嘗試從頭開始查找匹配項。

您幾乎沒有辦法解決此問題。

  1. let方法返回所有已建立匹配項的列表
  2. 傳遞Matcher的方法實例,這樣您就find在Matcher上調用find ,它會記住上一個匹配項在哪里,並在其后進行搜索。

我會選擇選項1,因為選項2只是包裝find方法並返回其結果,感覺像是太簡單的代碼,無法像單獨的方法

int getNextIndex(Matcher m){
    return matcher.find() ? matcher.start() : -1;
}

選項1可能看起來像

static Pattern pattern = Pattern.compile("[|]([*_@=])[^|]+\\1[|]");

public static List<Integer> getMatchedIntexes(String s) {
    List<Integer> result = new ArrayList<>();
    Matcher m = pattern.matcher(s);
    while (m.find()){
        result.add(m.start()+1);//index of character after `|`
        result.add(m.end()-1);  //index of character before `|`
    }

    return result;
}

你可以像這樣簡單地使用它

String textWithSpecialChars = "text here |*more*| text some other |@tags@|...";

for (int index : getMatchedIntexes(textWithSpecialChars))
    System.out.println(index);

將打印

11
17
36
42

[|]([*_@=])[^|]+\\\\1[|]

  • [|]\\\\|相同 代表| 文字
  • ([*_@=])創建組1,該組只能包含*_@=
  • [^|]+將匹配至少一個字符,而不是| (我假設您在|*...*| |內部沒有嵌套| |*...*|如果將其更改為.*? ,這可能會降低效率。
  • \\\\1代表來自組1的匹配,因此您只能找到|*..*| 部分,而不是|*.._|
  • 前面提到的[|]代表| 文字。

暫無
暫無

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

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