it-swarm-ja.tech

java.util.regex-Pattern.compile()の重要性?

Pattern.compile()メソッドの重要性は何ですか?
Matcherオブジェクトを取得する前に正規表現文字列をコンパイルする必要があるのはなぜですか?

例えば ​​:

String regex = "((\\S+)\\s*some\\s*";

Pattern pattern = Pattern.compile(regex); // why do I need to compile
Matcher matcher = pattern.matcher(text);
113
Sidharth

parses正規表現をコンパイルし、メモリ内表現を構築します。コンパイルのオーバーヘッドは、一致と比較してかなりのものです。パターン繰り返しを使用している場合、コンパイルされたパターンをキャッシュするためのパフォーマンスがいくらか得られます。

36
Thomas Jung

Pattern Javaをコンパイルすると、Stringsでの一致の検出を高速化するための計算が行われます。 (正規表現のメモリ内表現を構築します)

Patternを複数回再利用する場合、毎回新しいPatternを作成するよりも大幅にパフォーマンスが向上します。

パターンを1回だけ使用する場合、コンパイル手順は余分なコード行のように見えますが、実際には、一般的な場合に非常に役立ちます。

17
jjnguy

パフォーマンスとメモリ使用量の問題であり、コンパイルしたパターンを頻繁に使用する必要がある場合は、コンパイルして保持します。正規表現の一般的な使用法は、ユーザーを検証することです入力(形式)、およびユーザーの出力データの形式通常はたくさん呼ばれます。

以下はサンプルバリデータで、実際によく呼ばれています:)

public class AmountValidator {
    //Accept 123 - 123,456 - 123,345.34
    private static final String AMOUNT_REGEX="\\d{1,3}(,\\d{3})*(\\.\\d{1,4})?|\\.\\d{1,4}";
    //Compile and save the pattern  
    private static final Pattern AMOUNT_PATTERN = Pattern.compile(AMOUNT_REGEX);


    public boolean validate(String amount){

         if (!AMOUNT_PATTERN.matcher(amount).matches()) {
            return false;
         }    
        return true;
    }    
}

@Alan Mooreが述べたように、コードに再利用可能な正規表現がある場合(ループの前など)、再利用のためにパターンをコンパイルして保存する必要があります。

5
Alireza Fattahi

パターンクラスは、正規表現エンジンのエントリポイントです。Pattern.matches()およびPattern.comiple()を使用して使用できます。 #これら2つの違い。 matches()-テキスト(String)が指定された正規表現に一致するかどうかをすばやく確認しますcomiple()-Patternの参照を作成します。したがって、複数回使用して、正規表現を複数のテキストと照合できます。

参考のため:

public static void main(String[] args) {
     //single time uses
     String text="The Moon is far away from the Earth";
     String pattern = ".*is.*";
     boolean matches=Pattern.matches(pattern,text);
     System.out.println("Matches::"+matches);

    //multiple time uses
     Pattern p= Pattern.compile("ab");
     Matcher  m=p.matcher("abaaaba");
     while(m.find()) {
         System.out.println(m.start()+ " ");
     }
}
0
vkstream

正規表現をプリコンパイルすると、速度が向上します。マッチャーを再利用すると、もう少しスピードが上がります。メソッドが頻繁に呼び出され、ループ内で呼び出された場合、全体的なパフォーマンスは確実に上がります。

0
DragonBorn

Pattern.compile()正規表現を複数回再利用できます(スレッドセーフです)。パフォーマンス上のメリットは非常に大きい場合があります。

私は簡単なベンチマークを行いました:

    @Test
    public void recompile() {
        var before = Instant.now();
        for (int i = 0; i < 1_000_000; i++) {
            Pattern.compile("ab").matcher("abcde").matches();
        }
        System.out.println("recompile " + Duration.between(before, Instant.now()));
    }

    @Test
    public void compileOnce() {
        var pattern = Pattern.compile("ab");
        var before = Instant.now();
        for (int i = 0; i < 1_000_000; i++) {
            pattern.matcher("abcde").matches();
        }
        System.out.println("compile once " + Duration.between(before, Instant.now()));
    }

compileOnceは倍から4倍高速の間でした。私はそれが正規表現自体に大きく依存していると思いますが、頻繁に使用される正規表現については、static Pattern pattern = Pattern.compile(...)

0
apflieger

「Pattern.compile」と同様に、「RECompiler.compile」[com.Sun.org.Apache.regexp.internalから]があります。ここで、
1。パターン[a-z]のコンパイル済みコードには 'az'が含まれています
2。パターン[0-9]のコンパイル済みコードには '09'が含まれています
3。パターン[abc]のコンパイル済みコードには「aabbcc」が含まれています。

したがって、コンパイルされたコードは、複数のケースを一般化する素晴らしい方法です。したがって、異なるコード処理状況1,2および3を使用する代わりに。問題は、コンパイルされたコードの現在の要素と次の要素、つまりペアのasciiと比較することになります。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example
a。アスキーとaとzの間にあるものはすべてaとzの間にある
b。 「a」と「a」の間のアスキーを持つものはすべて「a」です