我使用以下regex来匹配@username字符串(twitter类似于用户名匹配系统)。
(?<!['w@])@(['w@]+(?:[.!]['w@]+)*)
这段代码对我来说是完美的,但是想要排除一种特定的情况:如果匹配的字符串是一组4位数字。只有4位数。如果有3位或5位数字,则应该像现在一样继续匹配。
例如:
@8500 <—don't match
@850 <——match
@8500000000 <——match
有没有任何人都能想到的简单修改?如果没有,我打算在PHP中做检查。
谢谢!
使用负向前看(?!...)
,您可以检查以下模式在当前位置是否不匹配:
(?<!['w@])@(?!'d'd'd'd'b)(['w@]+(?:[.!]['w@]+)*)
这里讨论的负前瞻性是(?!'d'd'd'd'b)
。该模式将匹配四个数字,然后是单词边界。通过反向向前看,这将匹配任何,而不是四位数字,然后是单词的结尾。
这假设一个有效的用户名不包含任何会导致词边界匹配的字符。如果@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
if(strlen($string) != 4){
...regex here...
}
您可以使用{min,max}
语法指定regex令牌的最小/最大匹配数,因此您可以使用这样的代码片段来匹配1-3或5个或更多数字('d
),由非数字字符('D
)包围:
/'D*('d{1,3}|'d{5,})'D*/