正規表現は、複数の選択肢の構造を注文します

正規表現は、複数の選択肢の構造を注文します

プログラミングの問題を見てください

[セクションからのみ含まれ.0- 9]文字列は、すべての可能なIPv4アドレスを抽出します。

IPv4アドレスは、小数点数やポイントによって表され、各アドレスは、4つの10進数の範囲が含まれ0-255、例えば172.16.254.1、ために同じ時間ではなく、4つの10進数0で始まるが、そのようなものが172.16.254.01合法的ではありません。

今テキスト入力str="1.1.1111.16..172.16.254.1.1"、アプリケーションによって形成された可能なすべてのサブストリング間のランダム項の文字列のIPv4アドレス。

多くの人々は、考えるIPv4的正则表达式我可熟悉啦,肯定能快速完成!の正規表現は、IPv4からインターネットを検索して、次のコードを記述します。

// Java语言
import java.util.*;
import java.util.regex.*;

class Solution {
    private static final Pattern IPV4_PATTERN =
            Pattern.compile("((([1-9][0-9]?)|(1[0-9]{2})|(2[0-4]\\d)|(25[0-5])|0)\\.){3}" +
                    "(([1-9][0-9]?)|(1[0-9]{2})|(2[0-4]\\d)|(25[0-5])|0)");

    public Set<String> findAllIpv4(String input) {
        Set<String> s = new TreeSet<String>();
        Matcher m = IPV4_PATTERN.matcher(input);
        int from = 0;
        while (m.find(from)) {
            s.add(input.substring(m.start(), m.end()));
            from++;
        }
        return s;
    }
}

私たちは、コードのこの部分を読んで、いることは確かである:正規表現、問題はないが、右のIPV4アドレスを確認するためにそれを使用することができます。2 Javaの正規表現APIの使用量は、予想に沿ったもので、あまり問題ではありません...

输入:0.0.0.255
输出:[0.0.0.25]

しかし、このコードの結果が正しくない、出力が正しいか[0.0.0.2, 0.0.0.25, 0.0.0.255]、定期的に交互に理由の嘘|使用に関する。

交替(交替)

別の定期的なエンジンで交替は、動作原理が異なっています。従来ではNFAマッチが完了すると、エンジン、複数の選択肢の枝の表現で左から右へ順にチェックされ、複数の選択肢の他のブランチはしようとしません1

例えば上記正規表現部、我々各進数のための別個の抽出式(([1-9][0-9]?)|(1[0-9]{2})|(2[0-4]\\d)|(25[0-5])|0)は、次の順序に一致します。

1. ([1-9][0-9]?)      # 一位数或两位数
2. (1[0-9]{2})        # 位于区间[100-199]的三位数
3. (2[0-4]\\d)        # 位于区间[200-249]的三位数
4. (25[0-5])          # 位于区间[250-255]的三位数
5. 0                  # 0

次に、入力文字列のための0.0.0.255第四の小数点実行する際のマッチング処理、255一致、優先度算出式を([1-9][0-9]?)、これはに合わせることができる252しながら?(question mark)貪欲数量詞である規則的に2従ってのみ残します25、その最後に、我々は、演算結果を参照してください[0.0.0.25]

前提知識で、我々はによって可能优先匹配多位数字,手工解析少量数字であるこれを行うには正解手順、前面に複数桁の複数選択枝を一致させるためにいくつかの調整を行うための正規表現の必要性、の方法(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)以下のように、コードは次のとおりです。

// Java语言
import java.util.*;
import java.util.regex.*;

class Solution {
    private static final Pattern IPV4_PATTERN =
            Pattern.compile("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}" +
                    "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)");

    public Set<String> findAllIpv4(String input) {
        Set<String> s = new TreeSet<String>();
        Matcher m = IPV4_PATTERN.matcher(input);
        int from = 0;
        int lastDotIdx = 0;
        String sub = null;
        while (m.find(from)) {
            sub = input.substring(m.start(), m.end());
            s.add(sub);
            lastDotIdx = sub.lastIndexOf('.');
            if (lastDotIdx == sub.length() - 3) {
                s.add(sub.substring(0, sub.length() - 1));
            } else if (lastDotIdx == sub.length() - 4) {
                s.add(sub.substring(0, sub.length() - 1));
                s.add(sub.substring(0, sub.length() - 2));
            }
            from++;
        }
        return s;
    }
}

  1. Friedlの、JE(2006)。正規表現をマスター。"オライリーメディア社"、P174-P175。

  2. Friedlの、JE(2006)。正規表現をマスター。"オライリーメディア社"、P142。

おすすめ

転載: www.cnblogs.com/imac/p/12077923.html