1

次の正規表現を使用して @username 文字列に一致させています (Twitter のようなユーザー名一致システム)。

(?<![\w@])@([\w@]+(?:[.!][\w@]+)*)

このコードは私にとっては完璧に機能していますが、1 つの特定のケースを除外したいと考えていました。一致する文字列が 4 桁のセットだった場合です。4桁のみ。3 桁または 5 桁の場合は、現在と同じように引き続き一致するはずです。

たとえば、次のようになります。

@8500 <-- 一致しない

@850 <-- マッチ

@8500000000 <-- 一致

誰でも思いつく簡単な修正はありますか?そうでない場合は、PHPでチェックを行うことを計画していました。

ありがとう!

4

3 に答える 3

3

否定先読みを使用すると、次のパターンが現在の位置で一致しない(?!...)かどうかを確認できます。

(?<![\w@])@(?!\d\d\d\d\b)([\w@]+(?:[.!][\w@]+)*)

ここで問題になっている否定的な先読みは です(?!\d\d\d\d\b)。パターンは 4 桁の数字と単語の境界に一致します。否定的な先読みによって反転され、これは 4 桁以外のすべてのものと単語の末尾に一致します

これは、有効なユーザー名に単語境界一致を引き起こす文字が含まれていないことを前提としています。が有効なユーザー名である場合@1234-hello、これは失敗し、PHP で照合を実行する必要があります。

テスト ケースの例を次に示します。

<?php

function test($test) {
    $pattern = '/(?<![\w@])@(?!\d\d\d\d\b)([\w@]+(?:[.!][\w@]+)*)/';
    echo (preg_match($pattern, $test) ? 'Matches' : 'No match') . "\n";
}

test('Hello @test world'); // Matches
test('Hello @123 world'); // Matches
test('Hello @1234 world'); // No match
test('Hello @12345 world'); // Matches
test('Hello @test1234 world'); // Matches
test('Hello @1234test world'); // Matches
test('Hello @1234-test world'); // No match
test('Hello @1234_test world'); // Matches
于 2013-03-20T04:37:19.320 に答える
3
if(strlen($string) != 4){
    ...regex here...
}
于 2013-03-20T04:32:49.583 に答える
1

構文を使用して正規表現トークンの一致の最小/最大数を指定できる{min,max}ため、次のようなスニペットを使用して、1 ~ 3 桁または 5 桁以上の数字 ( ) を数字以外の文字 ( )\dで囲んで一致させることができます。\D

/\D*(\d{1,3}|\d{5,})\D*/
于 2013-03-20T04:36:11.487 に答える