【问题标题】:Count occurrences of a character within a string when outside square brackets在方括号外计算字符串中字符的出现次数
【发布时间】:2014-05-19 18:01:07
【问题描述】:

短版:

如何计算字符串中@ 的数量,同时排除@ 内部的[ ]

加长版:

我正在编写一个简单的 php 类以允许使用 @NamedSqlParameterssqlsrv_query()(我意识到这已经可以使用 PDO_SQLSRV - 但据我了解,PDO_SQLSRV 仅在 Windows 环境中可用- 此类适用于使用 MS SQL Linux 驱动程序的 Debian 环境。

当用户传入@NamedParamaters 的数组时,我需要检查$CommandString 是否包含相同数量的@NamedParamaters,最初我虽然我使用substr_count() 来计算@987654332 的数量而侥幸@'s 但显然不会考虑与非参数相关的@'s - 以$CommandString 为例:

SELECT * FROM [@foo] WHERE ID = @ID AND BAR = @BAR

所以是的,我如何计算字符串中 @ 的数量,同时排除 @ 内部的 [ ] 的数量

我怀疑这里需要preg_match_all

【问题讨论】:

    标签: php sql regex


    【解决方案1】:

    你可以使用:

    $s = 'SELECT * FROM [@foo] WHERE ID = @ID AND BAR = @BAR';
    if ( preg_match_all('/\[[^]]*\]|(@)/', $s, $m) ) {
       $count = count(array_filter($m[1]));
       echo $count; // 2
    }
    

    【讨论】:

    • 它的切割器 :-) 在 $s 之间有一个额外的空间
    • 谢谢,错误已修复:)
    【解决方案2】:

    您可以使用技巧(*SKIP)(*FAIL) 跳过方括号之间的部分:

    $pattern = '~\[[^]]*](*SKIP)(*FAIL)|@~';
    
    $result = preg_match_all($pattern, $str, $matches);
    

    (*SKIP) 禁止在模式稍后失败时重试子字符串
    (*FAIL) 强制模式失败

    【讨论】:

    • 我不确定,但我不认为这是正确处理倍数,例如,它在以下情况下返回 1:SELECT * FROM [@foo] INNER JOIN [@bar] ON whatever = whatever WHERE ID = @ID AND BAR = @BAR AND WOOF = @WOOF - 无论哪种方式,anubhava 的答案都很好:)
    • @SabujHassan:很简单,您首先尝试匹配方括号内的内容(以确保替换的第二部分仅找到不在括号内的@)。 (*SKIP) 是一个回溯控制动词,当右侧的子模式失败时,它会强制正则表达式引擎不重试子字符串。 (*FAIL) 让它失败。
    • @HeavenCore:我忘了把[0]放在$matches后面!
    • @CasimiretHippolyte 您的另一个创意解决方案!!!嘿,您可能知道这一点,但您不需要count($match[0])。那是因为preg_match_all()返回的是匹配数,所以可以说$result = preg_match_all(etc)
    猜你喜欢
    • 2014-04-24
    • 2020-02-21
    • 2012-02-12
    • 2019-10-12
    • 2023-02-04
    • 2020-05-06
    相关资源
    最近更新 更多