web-dev-qa-db-ja.com

Java RegEx否定後読み

私は次のJavaコードを持っています:

_Pattern pat = Pattern.compile("(?<!function )\\w+");
Matcher mat = pat.matcher("function example");
System.out.println(mat.find());
_

mat.find()がtrueを返すのはなぜですか?ネガティブルックビハインドを使用し、exampleの前にfunctionを付けました。捨ててはいけませんか?

18
Sorin

一致するものを確認してください。

_public static void main(String[] args) throws Exception {
    Pattern pat = Pattern.compile("(?<!function )\\w+");
    Matcher mat = pat.matcher("function example");
    while (mat.find()) {
        System.out.println(mat.group());
    }
}
_

出力:

_function
xample
_

したがって、最初に「function」が前に付いていないfunctionを見つけます。次に、_function e_が前に付いているため「xample」ではないfunctionを見つけます。

おそらく、一致するものを見つけるだけでなく、パターンを全体テキストに一致させたいと思うでしょうinテキスト。

Matcher.matches()でこれを行うか、パターンを変更して開始アンカーと終了アンカーを追加できます。

_^(?<!function )\\w+$
_

2番目のアプローチの方が好きです。というのは、パターンがその用途によって定義される領域ではなく、パターン自体がその一致領域を定義することを意味するからです。ただし、これは好みの問題です。

32

文字列には、\ w +と一致する単語「function」があり、前に「function」が付いていません。

1
Antti Haapala

ここで2つのことに注意してください。

  • find()を使用しています。これは、sub-stringの一致に対してもtrueを返します。

  • 上記の理由により、「function」の前には「function」がないため、「function」は一致します。
    正規表現にスペースが含まれていないため、文字列全体が一致することはありません。

代わりに、Mathcher#matches()または^および$アンカーを負の先読みで使用します。

Pattern pat = Pattern.compile("^(?!function)[\\w\\s]+$"); // added \s for whitespaces
Matcher mat = pat.matcher("function example");

System.out.println(mat.find()); // false
1
Ravi Thapliyal