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