PHP:preg_match可以包含不匹配的组吗?

时间:2017-05-11 10:24:50

标签: php preg-match

preg_match()函数是否可以包含在匹配数组中找不到的组?

以下是我使用的模式:

  

/ ^([0-9] +)([0-9] +)?\ S?([^ IIBB])?([II])?([BB])?$ /

我尝试将人类可读的大小解析为字节。这种模式符合我的要求,但前提是我可以按绝对组顺序检索匹配。

这可以产生最多5个匹配组,这将导致匹配数组的索引为0-5。但是,如果字符串与所有组都不匹配,那么匹配数组可能具有例如实际上在索引3处的组5。

我喜欢的是该模式(5)中的最终匹配始终与matches数组的索引相同。因为多个组是可选的,所以在读取匹配数组时我们知道表达式中的哪个组匹配是非常重要的。

示例情况:regexr.com处的正则表达式测试人员将显示所有5个组,包括始终按正确顺序匹配的组。通过启用"全球"和"多线"标记并使用以下文本,您可以将鼠标悬停在蓝色匹配上以获得良好的视觉效果。

500.2 KiB
256M
700 Mb
1.2GiB

您会注意到并非所有组都始终匹配,但组索引的顺序始终正确。

编辑:是的我已经在PHP中尝试了以下内容:

$matches    = [];
$matchesC   = 0;
$matchesN   = 6;
if (!preg_match("/^([0-9]+)(\.[0-9]+)?\s?([^iIbB])?([iI])?([bB])?$/", $size, $matches) || ($matchesC = count($matches)) < $matchesN) {
    print_r($matches);
    throw new \Exception(sprintf("Could not parse size string. (%d/%d)", $matchesC, $matchesN));
}

$size为&#34; 256M&#34; print_r($matches);返回:

Array
(
    [0] => 256M
    [1] => 256
    [2] => 
    [3] => M
)

第4组和第5组缺失。

2 个答案:

答案 0 :(得分:1)

在PHP中没有使用空字符串值初始化非参与组,因此,对于'256M'字符串,第4组和第5组 null 。似乎preg_match丢弃了数组末尾的那些非初始化值。

在您的情况下,您可以使捕获组不可选,但可选的模式。

$arr = array('500.2 KiB', '256M', '700 Mb', '1.2GiB');
foreach ($arr as $s) {
    if (preg_match('~^([0-9]+)(\.[0-9]+)?\s?([^ib]?)(i?)(b?)$~i', $s, $m)) {
        print_r($m) . "\n";
    }
}

输出:

Array
(
    [0] => 500.2 KiB
    [1] => 500
    [2] => .2
    [3] => K
    [4] => i
    [5] => B
)
Array
(
    [0] => 256M
    [1] => 256
    [2] => 
    [3] => M
    [4] => 
    [5] => 
)
Array
(
    [0] => 700 Mb
    [1] => 700
    [2] => 
    [3] => M
    [4] => 
    [5] => b
)
Array
(
    [0] => 1.2GiB
    [1] => 1
    [2] => .2
    [3] => G
    [4] => i
    [5] => B
)

请参阅PHP demo

答案 1 :(得分:-1)

您可以使用T-Regx来轻松处理此类情况!它总是检查一个组是否匹配,即使它是最后一个也不匹配。它还可以区分public class StateProvinceKey { private String stateCode; private String countryCodeAlpha2; public IBMStateProvinceKey() { } public StateProvinceKey(String stateCode, String countryCodeAlpha2) { this.stateCode = stateCode; this.countryCodeAlpha2 = countryCodeAlpha2; } public String getStateCode() { return stateCode; } public void setStateCode(String stateCode) { this.stateCode = stateCode; } public String getCountryCodeAlpha2() { return countryCodeAlpha2; } public void setCountryCodeAlpha2(String countryCodeAlpha2) { this.countryCodeAlpha2 = countryCodeAlpha2; } public byte[] serialize(){ ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.writeValueAsBytes(this); } catch (JsonProcessingException e) { } return new byte[0]; } } (匹配为空)或""(不匹配):

null