我有AK747这个词,我使用正则表达式来检测一个字符串(至少2个字符ex:AK)后面跟一个数字(至少是数字ex:747)。 编辑:(对不起,我不清楚这些家伙) 我需要在上面执行此操作,因为:
在某些情况下,我需要拆分以匹配AK-747的搜索。当我搜索字符串' AK-747'关键字' AK747'除非我在数据库中使用levenshtein,否则它不会找到匹配,所以我更喜欢将AK747拆分为AK和747。
我的代码:
$strNumMatch = preg_match('/^[a-zA-Z]{2,}[0-9]{2,}$/',
$value, $match);
if(isset($match[0]))
echo $match[0];
如何使用preg_split()或任何其他方式拆分为数组[' AK',' 747']?
答案 0 :(得分:1)
你可以试试这个:
preg_match('/[0-9]{2,}/', $value, $matches, PREG_OFFSET_CAPTURE);
$position = $matches[0][1];
$letters = substr($value, 0, $position);
$numbers = substr($value, $position);
这样你就可以获得第一个数字的位置并在那里分开。
修改强>: 从你原来的方法开始,这可能看起来像这样:
$strNumMatch = preg_match('/^([a-zA-Z]{2,})([0-9]{2,})$/', $value, $match, PREG_OFFSET_CAPTURE);
if($strNumMatch){
$position = $matches[2][1];
$letters = substr($value, 0, $position);
$numbers = substr($value, $position);
$alternative = $letters.'-'.$numbers;
}
答案 1 :(得分:1)
$input = 'AK-747';
if (preg_match('/^([a-z]{2,})-?([0-9]{2,})$/i', $input, $result)) {
unset($result[0]);
}
print_r($result);
输出:
Array
(
[1] => AK
[2] => 747
)
答案 2 :(得分:1)
preg_split()
是一个非常明智和直接的调用,因为你需要一个包含两个子串的索引数组。
代码:(Demo)
$input = 'AK-747';
var_export(preg_split('/[a-z]{2,}\K-?/i',$input));
输出:
array (
0 => 'AK',
1 => '747',
)
\K
表示"重启全字符串匹配"。实际上,\K
左边的所有内容都保留为结果数组中的第一个元素,而右边的所有内容(可选连字符)都被省略,因为它被认为是分隔符。 Pattern Demo
代码:(Demo)
我处理了一小部分输入信息,以显示可以执行的操作并在摘录后解释。
$inputs=['AK747','AK-747','AK-','AK']; // variations as I understand them
foreach($inputs as $input){
echo "$input returns: ";
var_export(preg_split('/[a-z]{2,}\K-?/i',$input,2,PREG_SPLIT_NO_EMPTY));
echo "\n";
}
输出:
AK747 returns: array (
0 => 'AK',
1 => '747',
)
AK-747 returns: array (
0 => 'AK',
1 => '747',
)
AK- returns: array (
0 => 'AK',
)
AK returns: array (
0 => 'AK',
)
preg_split()采用一种模式,该模式接收与变量子字符串匹配的模式,并将其用作分隔符。如果每个输入字符串中都存在-
,则explode('-',$input)
最合适。但是,-
在此任务中是可选的,因此模式必须允许-
是可选的(这是?
量词在此页面上的所有模式中的作用)。
现在,您无法使用/-?/
,that would split the string on every character这样的模式。要解决此问题,您需要告诉正则表达式引擎可选-
的确切预期位置。您可以通过在[a-z]{2,}
(单个预定分隔符)之前引用-?
来执行此操作。
模式/[a-z]{2,}-?/i
可以很好地找到可选连字符的正确位置,但现在问题是,字符串中的前导字母包含在part of the delimiting substring中。
有时,#34; lookarounds&#34;可以在正则表达式模式中使用以匹配但不消耗子字符串。 A&#34;积极的背后&#34;用于匹配前面的子字符串,但"variable length lookbehinds" are not permitted in php (and most other regex flavors)。这就是无效模式的样子:/(?<=[a-z]{2,})-?/i
。
围绕这种技术性的方法是重新开始全字符串匹配&#34;在可选连字符之前使用\K标记(又名a lookbehind alternative)。要正确地仅针对预期的分隔符,必须使用前导字母匹配/消费&#34;然后&#34;丢弃&#34; - 这是\K
的作用。
至于包含preg_split()
...
2
。这与limit
具有的explode()
参数类似。它指示函数不要生成超过2个输出元素。对于这种情况,我可以使用NULL
或-1
表示&#34;无限制&#34;,但我不能将参数留空 - 必须将其指定为允许声明第四个参数。PREG_SPLIT_NO_EMPTY
,指示函数不生成空输出元素。钽沓!
P.S。 preg_match_all()
solution与使用管道和两个锚点一样简单:
$inputs=['AK747','AK-747','AK-','AK']; // variations as I understand them
foreach($inputs as $input){
echo "$input returns: ";
var_export(preg_match_all('/^[a-z]{2,}|\d{2,}$/i',$input,$out)?$out[0]:[]);
echo "\n";
}
// same outputs as above
答案 3 :(得分:0)