【问题标题】:String search function to return boolean if needle is found in haystack如果在 haystack 中找到针,则字符串搜索函数返回布尔值
【发布时间】:2017-12-20 16:16:33
【问题描述】:

我正在编写一个简单的函数,它将包含 url 的字符串转换为可点击的链接。转换本身很简单,但如果字符串包含协议前缀之一,则作为基本验证的一部分似乎非常困难。

目前我的代码如下所示:

<?php

function link2code($link) {
    if (stripos($link, 'http://' or 'https://' or 'ftp://' or 'ftps://') === true) {
        return "<a href=\"$link\">$link</a>";
    } else {
        echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
    }
}

echo link2code("http://127.0.0.1");

如您所见,我想返回布尔值来判断针是否在大海捞针中。我怎样才能实现它?

【问题讨论】:

标签: php string stripos


【解决方案1】:

你可以使用 in_array()。
http://php.net/manual/en/function.in-array.php

function link2code($link) {
    $arr = array('http:/', 'https:', 'ftp://', 'ftps:/');
    If(in_array(substr($link,0,6), $arr)){
        return "<a href=\"$link\">$link</a>";
    } else {
         echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
    }
}

echo link2code("https://127.0.0.1");

https://3v4l.org/meI1r
该数组包含最小公共字符数 (6),以便我可以在函数中与相同的字符进行比较。
因此,如果它们与数组不匹配,substr 将查看前六个字符,它不是唯一的链接字符串。

意思是字符串click here https://127.0.0.1会失败

当然,如果您不需要验证它是否是仅链接字符串,您可以从代码中删除 substr 并在数组中添加“完整”项。

【讨论】:

    【解决方案2】:

    尝试使用正则表达式和preg_match

    function link2code($link) {
        if ( ! preg_match('/^(http(s)?|ftp(s)?):\/\//i', $link)) {
            echo 'Please provide whole link with protocol part, for example: http://myawesomewebsite.com';
            return FALSE;
        }
        return sprintf('<a href="%1$s">%1$s</a>', $link);
    }
    
    echo link2code("http://127.0.0.1");
    echo link2code("https://127.0.0.1");
    

    【讨论】:

      【解决方案3】:

      您可以尝试重新表述问题:

      不要检查链接中的协议是否之一,而是尝试检查链接中的协议是否是协议之一:

      function link2code($link) {
      
          $scheme = parse_url($link, PHP_URL_SCHEME);
          if(!in_array($scheme,['http','https','ftp','ftps']) {
              return "<a href=\"$link\">$link</a>";
          } else { 
              echo ()
          }
      }
      

      超出您的问题范围:

      你的函数做了不同的事情:

      • 验证网址
      • 返回字符串或返回 void
      • 在某些情况下会产生呼应。

      您可以尝试将验证与格式化分开,并确保您的函数始终返回字符串,或抛出异常。

      function link2code($link) {
          if(validateLink($link)) {
              return "<a href=\"$link\">$link</a>";
          } else {
              throw new \Exception("Please provide whole link with protocol part, for example: http://myawesomewebsite.com'");
          }
      }
      
      function validateLink($link) {
          $scheme = parse_url($link, PHP_URL_SCHEME);
          return in_array($scheme,['http','https','ftp','ftps']);
      }
      

      【讨论】:

      • 很高兴您使用url_parse
      【解决方案4】:

      可以使用正则表达式来完成。 尽管多次使用 stripos() 也可以。 这条线会更长,但可能更便宜。

      为了可读性,我更喜欢正则表达式

      <?php
      
      function link2code($link) {
          if (preg_match('#^(https?|ftps?)://#i', $link)) {
              return "<a href=\"$link\">$link</a>";
          } else {
              echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
          }
      }
      
      echo link2code("http://127.0.0.1");
      

      【讨论】:

        【解决方案5】:

        您可以为此使用preg_match

        if(preg_match("~^(ht|f)tps?://~i", $link)) { //...etc
        

        【讨论】:

        • 这么小的任务是不是有点繁重的功能?
        • 在我看来不是。这是一个简单的模式,所以基于正则表达式的匹配不会那么重。请注意 OP 代码(和一些答案)如何不验证匹配项是否位于字符串的开头。
        • 我发现这种方法是最优雅和最令人满意的,因为我想避免使用数组。正则表达式是强大的工具。感谢您的帮助,现在代码按我想要的方式工作。附言我对这个线程的答案的数量和多样性印象深刻。我也要感谢这里的所有其他人的建议。
        • @spectatorx 是的,正则表达式很强大。这个任务太强大了。此线程中的正则表达式答案比非正则表达式(不是全部)慢约 50%。只是出于好奇,您对数组的“问题”是什么?
        • 没有反对数组,我只是认为在这种情况下它们不是必需的,但这只是个人和非常情境偏好。
        【解决方案6】:

        签出此代码:

        class Test
        {
        
             public function index()
             {
                 $link = "http://127.0.0.1";
                 $this->checkLink("http://127.0.0.1");        //Yes
                 $this->checkLink("hsttp://127.0.0.1");        //No
             }
        
             private function checkLink($link)
             {
                 if (stripos($link, 'http://') !== false
                     || stripos($link, 'http://') !== false
                     || stripos($link, 'ftp://') !== false
                     || stripos($link, 'ftps://') !== false)
                 {
                     echo 'Yes';
                 }
                 else
                 {
                     echo 'No';
                 }
              }
        
        }
        

        【讨论】:

          【解决方案7】:

          您可以通过定义自定义函数进行迭代并找到 if match found 创建一个链接。

          function strPosition($haystack, $needle, $offset=0) {
            if (!is_array($needle)) $needle = array($needle);
              foreach ($needle as $query) {
                if (strpos($haystack, $query, $offset) !== false) return true; // stop on first true result
              }
              return false;
          }
          
          function link2code($link) {
            $array = array('http://', 'https://', 'ftp://', 'ftps://');
          
            $match = strPosition($link, $array);
            if ($match == true) {
              return "<a href=\"$link\">$link</a>";
            } else {
              echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
            } 
          }
          

          【讨论】:

            猜你喜欢
            • 2021-10-22
            • 2021-06-28
            • 1970-01-01
            • 2023-03-20
            • 1970-01-01
            • 1970-01-01
            • 2022-12-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多