我想标记格式化字符串(非常类似于printf),我想我只是遗漏了一点点:
我在the regExp simulator走得很远。看起来应该这样做:
²update:现在使用#而不是%。 (使用Windows命令行参数减少麻烦)
如果你专注于通过管道连接的三个部分(作为 - 或者),这并不可怕,所以基本上它只是三个匹配。由于我想从头到尾进行匹配,因此我将内容包裹在/^...%/
中,并由不匹配的组(?:...
包围,可能会重复一次或多次:
$exp = '/^(?:(%\\d*[ctYymd]+)|([^$%]+)|(\\$\\d))+$/';
我的来源仍未提供:
$exp = '/^(?:(%\\d*[ctYymd]+)|([^$%]+)|(\\$\\d))+$/';
echo "expression: $exp \n";
$tests = [
'###%04d_Ball0n%02d$1',
'%03d_Ball0n%02x$1%03d_Ball0n%02d$1',
'%3d_Ball0n%02d',
];
foreach ( $tests as $test )
{
echo "teststring: $test\n";
if( preg_match( $exp, $test, $tokens) )
{
array_shift($tokens);
foreach ( $tokens as $token )
echo "\t\t'$token'\n";
}
else
echo "not valid.";
} // foreach
我得到了结果但是:匹配失灵了。第一个%[数字] [字母]从不匹配,因此其他人匹配双倍:
expression: /^((%\d*[ctYymd]+)|([^$%]+)|(\$\d))+$/
teststring: ###%04d_Ball0n%02d$1
'$1'
'%02d'
'_Ball0n'
'$1'
teststring: %03d_Ball0n%02x$1%03d_Ball0n%02d$1
not valid.teststring: %3d_Ball0n%02d
'%02d'
'%02d'
'_Ball0n'
teststring: %d_foobardoo
'_foobardoo'
'%d'
'_foobardoo'
teststring: Ball0n%02dHamburg%d
'%d'
'%d'
'Hamburg'
答案 0 :(得分:2)
解决方案(由OP编辑):我使用两个略微变化(仅涉及'换行'):首先用于验证,然后用于标记化:
#\d*[ctYymd]+|\$\d+|[^#\$]+
<强>代码:强>
$core = '#\d*[ctYymd]+|\$\d+|[^#\$]+';
$expValidate = '/^('.$core.')+$/m';
$expTokenize = '/('.$core.')/m';
$tests = [
'#3d-',
'#3d-ABC',
'***#04d_Ball0n#02d$1',
'#03d_Ball0n#02x$AwrongDollar',
'#3d_Ball0n#02d',
'Badstring#02xWrongLetterX'
];
foreach ( $tests as $test )
{
echo "teststring: [$test]\n";
if( ! preg_match_all( $expValidate, $test) )
{
echo "not valid.\n";
continue;
}
if( preg_match_all( $expTokenize, $test, $tokens) ) {
foreach ( $tokens[0] as $token )
echo "\t\t'$token'\n";
}
} // foreach
<强>输出:强>
teststring: [#3d-]
'#3d'
'-'
teststring: [#3d-ABC]
'#3d'
'-ABC'
teststring: [***#04d_Ball0n#02d$1]
'***'
'#04d'
'_Ball0n'
'#02d'
'$1'
teststring: [#03d_Ball0n#02x$AwrongDollar]
not valid.
teststring: [#3d_Ball0n#02d]
'#3d'
'_Ball0n'
'#02d'
teststring: [Badstring#02xWrongLetterX]
not valid.