【问题标题】:php find a substring only if it's not part of another substringphp 仅当它不是另一个子字符串的一部分时才查找子字符串
【发布时间】:2016-12-21 20:56:43
【问题描述】:

我知道如何使用 strpos 查找子字符串,但我只想在字母 t 出现在字符串中时返回 True,但如果 t 后跟“he”则不返回。例如... $str="The lion and dog are hungry" 结果将是Does not contain t,因为字符串中唯一的 t 是单词“The”的一部分。 $str="Their bedroom is ugly" 也应该返回 false,因为 "Their" 以 T H E 开头并且字符串中没有其他 t。 $str="The cat and the dog are hungry" 将导致 Yes, this string contains a t,因为 CAT 中有一个 t。

【问题讨论】:

    标签: php string substring


    【解决方案1】:

    试试这个

    <?php
    $a = 'Their bedroom is ugly';
    
    if (preg_match('/t(?!he)(?!his)/i',$a))
        echo 'true';
    else
        echo 'false';
    

    【讨论】:

    • 感谢您的快速回答。还有一个问题......我不擅长正则表达式,我将如何添加另一个条件,例如,如果我不想包含 THE 或 THI 所以The boy and this girl 会导致错误,因为唯一的 T 是在和这个。
    • /t[^the]/ 匹配t,后跟 1 个字符,而不是 the
    • @WiktorStribiżew 我认为如果文本末尾的字母 T 不会返回 true,您可以尝试更新答案
    • 您可以在最后一个 '/' 之后添加一个 'i' 以使正则表达式不区分大小写。您也可以将 't' 替换为字符类 '[tT]',以便匹配 't' 或 'T',您也可以使用 an 或 '|'像这样't|T'
    • 我认为使用 /i 修饰符是首选方式。另外,(?!he)(?!his) 看起来太冗长了,在前瞻中使用交替也可以达到相同的效果:(?!he|his),有关详细信息,请参阅我的答案。
    【解决方案2】:

    您需要一个否定的正则表达式:

    /t(?!h(?:e|is))/i
    

    regex demo

    模式详情

    • t - 文字字符 t
    • (?!h(?:e|is)) - 一个否定的lookbehind,检查它的模式是否与当前位置之后的字符串匹配,如果匹配发生则匹配失败(返回false):
      • h - 文字 h
      • (?:e|is) - eis(?:...|...) 是一个非捕获组,不会在包含 | 交替运算符的内存中保留子匹配)
    • /i - 不区分大小写的修饰符使正则表达式以不区分大小写的方式匹配。

    基本上,这是t(?!he|his) 正则表达式的更高效版本(t 后面没有hehis)。

    PHP demo:

    $re = '/t(?!h(?:e|is))/i';
    
    if (preg_match($re,'The cat and the dog are hungry'))
        echo 'true';
    else
        echo 'false';
    

    【讨论】:

    • /t(?!he)(?!his)/i 因为提问者在回复中更新了他的问题
    • @Mostafa:好的,我调整了图案,更新了demo链接。
    • 很好,详细的答案。我实际上选择了效率较低的t(?!he|his),这对我来说很好,而且很容易理解。
    • 对于正则表达式,最佳实践是确保它们匹配线性,前一个子模式不应与下一个子模式在同一位置匹配。因此,使用以相同字符开头的替代分支不是一个好主意。我同意在这个具体案例中不会对性能产生太大影响,但是如果您考虑扩展模式,或者将其放入更长的模式,您应该牢记这一点。
    【解决方案3】:

    您可以使用 strpos 检查您找到的所有 't' 之后是否有 'he':

    <?php
    $offest = 0;
    $string = "the t the";
    $result = 'No, this string does not contain t';
    while ($pos1 = strpos($string,'t', $offset)) {
        if ($pos2 = strpos($string,'the',$offset) {
            if ($pos1 != $pos2) {
                $result = 'Yes, this string contains t';
            } else {
                $offset = pos1;
            }
        } else {
            $result = 'Yes, this string contains t';
        }
    }
    echo $result;
    

    但这不是最有效的方法。恕我直言,最好的办法是使用Regex

    $string = "the t the";
    $result = 'no';
    if (preg_match('/[tT][^Hh]/')) {
        $result = 'yes';
    }
    

    你也可以使用negative lookahead(个人最喜欢的技术):

    $string = "the t the";
    $result = 'no';
    if (preg_match('/t(?!he)/i')) {
        $result = 'yes';
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 2019-05-11
      • 2022-06-17
      • 1970-01-01
      • 2015-03-21
      相关资源
      最近更新 更多