0

私はJavaの基本を知っていますが、正規表現やパターンの経験があまりないので、非常に簡単なことを尋ねたらすみません.. IPアドレスとホスト名を検出するメソッドを書いています。ここでこの回答の正規表現を使用しました。私が遭遇している問題は、記号のない文がホスト名としてカウントされることです

私のコードは次のとおりです。

    Pattern validHostname = Pattern.compile("^(([a-z]|[a-z][a-z0-9-]*[a-z0-9]).)*([a-z]|[a-z][a-z0-9-]*[a-z0-9])$",Pattern.CASE_INSENSITIVE);
    Pattern validIpAddress = Pattern.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])([:]\\d\\d*\\d*\\d*\\d*)*$",Pattern.CASE_INSENSITIVE);
    String msg = c.getMessage();
    boolean found=false;

    //Randomly picks from a list to replace the detected ip/hostname
    int rand=(int)(Math.random()*whitelisted.size());
    String replace=whitelisted.get(rand);

    Matcher matchIP = validIpAddress.matcher(msg);
    Matcher matchHost = validHostname.matcher(msg);

    while(matchIP.find()){
        if(adreplace)
            msg=msg.replace(matchIP.group(),replace);
        else
            msg=msg.replace(matchIP.group(),"");

        found=true;
        c.setMessage(msg);
    }
    while(matchHost.find()){
        if(adreplace)
            msg=msg.replace(matchHost.group(),replace);
        else
            msg=msg.replace(matchHost.group(),"");

        found=true;
        c.setMessage(msg);
    }
    return c;
4

1 に答える 1

2

説明

サンプル テキストと必要な出力がなくても、質問に答えるために最善を尽くします。

ホスト名の式を次のように書き直します。

A: の ^(?:[a-z][a-z0-9-]*[a-z0-9](?=\.[a-z]|$)\.?)+$ような単一の単語名を許可しますabcdefg

B: ^(?=(?:.*?\.){2})(?:[a-z][a-z0-9-]*[a-z0-9](?=\.[a-z]|$)\.?)+$のように少なくとも 2 つのピリオドを含む文字列が必要abc.defg.comです。これにより、ピリオドを開始または終了、または連続したピリオドに表示することはできなくなります。先読み内の数字{2}は、出現しなければならないドットの最小数を示しています。この数は必要に応じて変更できます。

ここに画像の説明を入力

  • ^文字列アンカーの開始に一致
  • (?:非キャプチャ グループを開始すると、パフォーマンスが向上します
  • [a-z][a-z0-9-]*[a-z0-9]元の表現から取得した一致テキスト
  • (?=\.[a-z]|$)次の文字がドットの後に az 文字が続くかどうか、または文字列の末尾かどうかを確認します。
  • \.?存在する場合は単一のドットを消費します
  • )キャプチャ グループを閉じる
  • +キャプチャ グループのコンテンツが 1 回以上存在する必要があります
  • $文字列アンカーの末尾に一致

ホスト名:
Aドットなしのホスト名を許可する
Bホスト名にドットを含める必要がある

記号のない文章によるライブデモ

IP式も書き直します

^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?::\d*)?$

ここでの主な違いは次のとおりです。

  • 複数の \d* を末尾から削除しました。これは、式\d*\d*\d*\d*\d*\d*が次と同等であるためです。\d*
  • 文字クラス[:]を単一の文字に変更しました:
  • (キャプチャ グループを...)非キャプチャ グループに変えました(?...)パフォーマンスが少し向上しました。
于 2013-08-22T13:46:49.410 に答える