2

DNS サーバーに新しいドメインを追加するスクリプトを作成したいと考えています。完全修飾ドメイン名の検証REGEX . ただし、sed で使用すると、期待どおりに動作しません。

echo test | sed  '/(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(:[a-zA-Z]{2,})$)/p'  
--------
Output is: 
test
echo test.com | sed  '/(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(:[a-zA-Z]{2,})$)/p'  
--------
Output is: 
test.com

最初のコマンドの出力は空白行になるはずだと思っていました。私は何を間違っていますか?

4

6 に答える 6

12

これはより包括的な正規表現であることがわかりました。

(?=^.{4,253}$)(^(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){0,61}[a-zA-Z0-9])?\.)+([a-zA-Z]{2,}|xn--[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$)

  • RFC 1034§3: 4-25 3の長さを許可し、私が知っている最短の運用ドメイン「t.co」で、他の回答が一致しない場所でも一致します。255 バイトが最大長で、各ラベル (TLD および「プライマリ」サブドメイン) の長さのオクテットを引いた値は 253 になります。(?=^.{4,253}$)
    • RFC 3696§2 : 1 文字の TLD技術的に許可されています。つまり、最小の長さは 3 ですが、現在は 1 文字の TLD がないため、最小の長さの 4 が実用的です。
  • RFC 1034§3 : サブドメインで番号を許可しますが、Conor Clafferty は明らかに許可していません (他のサブドメインを「プライマリ」サブドメイン (つまり、登録するドメイン) と区別しないことにより、DNS 仕様では許可されません)
  • RFC 1034§3 : 個々のラベルを 63 文字に制限し、先頭と末尾を英数字に制限しながら中間のハイフンを許可します(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){,61}[a-zA-Z0-9])?\.)
  • 2 文字以上の TLD が必要ですが、 punycodeの場合があります ([a-zA-Z]{2,}|xn--[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])
    • RFC 3696§2 : DNS 仕様では、技術的には TLD 内の数値と 1 文字の TLD が許可されています。ただし、現在のところ、1 文字の TLD または数字を含む TLD はなく、すべて数字の TLD は許可されていないため、正規表現のこの部分は に簡略化されてい[a-zA-Z]{2,}ます。

      - また -

    • RFC 3490§5 : 国際化ドメイン名 ccTLD (IDN c​​cTLD) は、「xn--」プレフィックスで示されるように、punycode することができ、その後に文字、数字、またはハイフンを含めることができます。これはおおよそxn--[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]

      このパターンはPunycode TLDを検証しないことに注意してください。無効な punycode は許容されます (例: "xn--qqqq")。これは、適切なエンコード メカニズムに対して punycode を検証しようとする試みは、正規表現の範囲を超えているためです。punycode 自体は、技術的にはハイフンで終わるエンコードされた文字列を許可していますが、RFC 3492§5は、ラベルがハイフンで終わってはならないという IDNA の制限を観察し、尊重しています。

EDIT 02/2021: IDN c​​cTLD が以前に指定された正規表現と一致しなかったことを指摘したuser2241415へのハット チップ。

于 2014-11-10T18:02:57.180 に答える
3

正規表現に疑問符がありません:

(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)

ここで正規表現をテストできます

grep でやりたいことができます:

$ echo test.com | grep -P '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)'
test.com
$ echo test | grep -P '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)'
$
于 2013-03-07T13:20:46.780 に答える
1

sed私が知っている実装では、その正規表現で使用しているさまざまな Perl 拡張機能をサポートしていません。Perl またはgrep -Pまたはpcregrepで試すか、正規表現を単純化してsed対処できるものにします。これは、正規表現を 3 つの異なる正規表現のスクリプトに分割し、何かが一致しない (または最も中間の場合は一致する) 場合に拒否する、手早く汚い適応です。

echo 'test' | sed -r '/^.{5,254}$/!d
    /^([^.]*\.)*[0-9]+\./d   # Seems incorrect; 112.com is valid
    /^([a-zA-Z0-9_\-]{1,63}\.?)+([a-zA-Z]{2,})$/!d'  # should disallow underscore
    # also, what's with the question mark after the literal dot?

また、これは IDNA ドメイン (特に TLD にダッシュや数字を含めることができます) を完全に受け入れることができないため、これは絶対にお勧めしませんが、必要に応じてこのようなものを適応させる方法を示してくれることを願っていますsed.

于 2015-02-17T12:50:48.103 に答える
0

Pierre-Louis の答えは、私にとってはうまくいきませんでした。たとえば、「kittens」はドメイン名と見なされます。ドメインに少なくともドットが含まれるように、わずかな調整を 1 つ追加しました。

(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+\.(?:[a-z]{2,})$)

\.ドメインの最後の部分を読み取る直前に余分なものがあります。

于 2013-08-07T13:21:29.720 に答える
0

grep -Pはこれを行うために使用します。

echo test | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$" 
--------
Output is: 

echo www.test.com | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$"
--------
Output is: www.test.com
于 2016-10-06T17:17:05.847 に答える