簡體   English   中英

Pattern Matcher Vs String Split,我應該使用哪個?

[英]Pattern Matcher Vs String Split, which should I use?

第一次發帖。

首先我知道如何使用Pattern Matcher和String Split。 我的問題最適合我在我的例子中使用,為什么? 或建議更好的替代品。

任務:我需要在未知字符串中的兩個已知正則表達式之間提取未知的NOUN。

我的解決方案:獲取名詞的開頭和結尾(來自Regexp 1和2)和子串來提取名詞。

String line = "unknownXoooXNOUNXccccccXunknown";
int goal = 12 ;
String regexp1 = "Xo+X";
String regexp2 = "Xc+X";
  1. 我需要在第一個正則表達式之后找到索引位置。
  2. 我需要在第二個正則表達式之前找到索引位置。

A)我可以使用模式匹配器

    Pattern p = Pattern.compile(regexp1);
    Matcher m = p.matcher(line);
    if (m.find()) {
        int afterRegex1 = m.end();
    } else {
        throw new IllegalArgumentException();
        //TODO Exception Management;
    }

B)我可以使用String Split

    String[] split = line.split(regex1,2);
    if (split.length != 2) {
        throw new UnsupportedOperationException();
        //TODO Exception Management;
    }
    int afterRegex1 = line.indexOf(split[1]);

我應該使用哪種方法?為什么? 我不知道哪個在時間和記憶上更有效率。 兩者都足夠接近我自己的可讀性。

我這樣做:

String line = "unknownXoooXNOUNXccccccXunknown";
String regex = "Xo+X(.*?)Xc+X";

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(line);
if (m.find()) {
   String noun = m.group(1);
}

(.*?)用於使NOUN上的內部匹配不情願 這可以保護我們免受我們的結束模式再次出現在字符串的未知部分的情況。

編輯

這是有效的,因為(.*?)定義了一個捕獲組 在模式中只定義了一個這樣的組,因此它獲得索引1( m.group(1)的參數)。 這些組從1開始從左到右編制索引。如果模式定義如下

String regex = "(Xo+X)(.*?)(Xc+X)";

然后會有三個捕獲組,這樣

m.group(1); // yields "XoooX"
m.group(2); // yields "NOUN"
m.group(3); // yields "XccccccX"

一組0,但整個模式匹配,它的等效於此

m.group(); // yields "XoooXNOUNXccccccX"

有關使用Matcher可以執行的操作的更多信息,包括在源字符串中獲取模式的開始和結束位置的方法,請參閱Matcher JavaDocs

除非你處於緊密循環中,否則你應該使用String.split()來提高可讀性。

每個split()的javadocsplit()都相當於Pattern.compile() ,如果你處於緊密循環中,你可以優化它。

看起來你想要得到一個獨特的事件。 這樣做很簡單

input.replaceAll(".*Xo+X(.*)Xc+X.*", "$1")

為了提高效率,請使用Pattern.matcher(input).replaceAll

如果輸入包含換行符,請使用Pattern.DOTALLs修飾符。


如果您想使用拆分,請考慮使用Guava的Splitter 它表現得更加清醒,並且還接受一種對速度有益的Pattern

如果你真的需要這些位置,你可以這樣做:

String line = "unknownXoooXNOUNXccccccXunknown";
String regexp1 = "Xo+X";
String regexp2 = "Xc+X";

Matcher m=Pattern.compile(regexp1).matcher(line);
if(m.find())
{
  int start=m.end();
  if(m.usePattern(Pattern.compile(regexp2)).find())
  {
    final int end = m.start();
    System.out.println("from "+start+" to "+end+" is "+line.substring(start, end));
  }
}

但如果你只需要中間的這個詞,我推薦Ian McLaird所展示的方式。

暫無
暫無

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

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