【问题标题】:How to check if a string starts with a specified string? [duplicate]如何检查字符串是否以指定字符串开头? [复制]
【发布时间】:2011-02-16 23:13:13
【问题描述】:

我正在尝试检查一个字符串是否以http 开头。我该如何进行这项检查?

$string1 = 'google.com';
$string2 = 'http://www.google.com';

【问题讨论】:

  • 你可能想试试this standalone library,它可以在没有任何框架的情况下使用。它包括区分大小写和不区分大小写版本的startsWithendsWith
  • 由于它是一个使用如此广泛的框架,值得一提的是,如果你使用 Laravel,你可以使用 starts_withends_with 辅助函数。
  • PHP 8.0 为这项工作引入了新方法 str_starts_withstr_end_with: stackoverflow.com/a/64160081/7082164
  • 或者只是你可以使用 preg_match 并编写你自己的规则来检查它是否以 HTTPS 开头。您可以查看php.net/manual/en/function.preg-match.php 的 PHP 文档

标签: php


【解决方案1】:

PHP 8 或更新版本:

使用str_starts_with函数:

str_starts_with('http://www.google.com', 'http')

PHP 7 或更早版本:

使用substr 函数返回字符串的一部分。

substr( $string_n, 0, 4 ) === "http"

如果您要确保它不是其他协议。我会改用 http://,因为 https 也会匹配,以及其他东西,例如 http-protocol.com。

substr( $string_n, 0, 7 ) === "http://"

一般来说:

substr($string, 0, strlen($query)) === $query

【讨论】:

  • 如果您的指针是变量,则无需硬编码字符串长度,如下所述。只需使用 substr( $string, 0, strlen($query) ) === $query。
  • 使用多字节 utf8 字符串时要小心! mb_substr 是你的朋友
  • 使用substr($string, 0, strlen($query)) === $query时不需要使用mb_*函数
  • awgy 的 strpos 解决方案使用更少的资源..
  • @JesseSteele 它的位置,长度而不是开始位置,结束位置
【解决方案2】:

使用strpos():

if (strpos($string2, 'http') === 0) {
   // It starts with 'http'
}

记住三个等号 (===)。如果只使用两个,它将无法正常工作。这是因为如果在大海捞针中找不到针,strpos() 将返回 false

【讨论】:

  • 如果您只需要查看特定位置,则无需搜索整个字符串(strpos 如果找到针或到达末尾则停止)。
  • 请改用 substr,因为 strpos 在整个大海捞针中搜索针,而 substr 只检查开头(这对于长字符串最快)
  • @doublemarked 不,substr性能优势,这就是 Gumbo 的观点。当然,如果在字符串的开头找到了 needle,strpos 会提前返回,但如果 not 找到它,它将不必要地搜索整个字符串。这里有一个权衡; strpos 减少了导致错误的机会,但 substr 理论上应该表现更好,我想如果你的干草堆是一些巨大的字符串,比如小说的文本,这可能会很重要。由于您给出的原因,我总是使用strpos,但我对这两个答案都投了赞成票; substr 可能有它的位置。
  • 这是一个小问题,但向后比较的风格是反直觉的。我建议编辑答案以使用常规比较顺序。 (曾经有一个微不足道的原因,一些程序员这样做了一段时间,但这不是必需的。)它更具可读性和直观性,如“if (strpos($string2, 'http') === 0) ...
  • @orrd 嗯... yeeeees,尤达条件;不必要的,它是。 hrrrrm,使用它,你不应该。
【解决方案3】:

还有strncmp() 函数和strncasecmp() 函数非常适合这种情况:

if (strncmp($string_n, "http", 4) === 0)

一般:

if (strncmp($string_n, $prefix, strlen($prefix)) === 0)

substr() 方法相比的优势在于strncmp() 只做需要做的事情,而无需创建临时字符串。

【讨论】:

  • strncmp() 很好,因为它不会像 substr() 那样产生垃圾。它也比 strpos() 好,因为它不需要扫描整个字符串。这不太方便,因为您必须实际硬编码或计算前缀的长度,如果您以后弄错/更改它,该函数可能会停止工作。
  • 哇,这个简单的问题有很多答案。我选择你的最好:只需返回 strncmp($url, 'http', 4) === 0。手册中有很多字符串函数可供选择,但这显然适合这个问题,我冒险猜测它是表现最好的。
  • 这是一个非常好的答案,并且确实确实要求比较字符串的开头,而不是查找,比较。不知道为什么这不是选择的答案或没有这么少的赞成票。
  • 这绝对应该是最快的方式
【解决方案4】:

您可以使用简单的正则表达式(用户 viriathus 的更新版本,因为 eregi 已弃用)

if (preg_match('#^http#', $url) === 1) {
    // Starts with http (case sensitive).
}

或者如果您想要不区分大小写的搜索

if (preg_match('#^http#i', $url) === 1) {
    // Starts with http (case insensitive).
}

正则表达式允许执行更复杂的任务

if (preg_match('#^https?://#i', $url) === 1) {
    // Starts with http:// or https:// (case insensitive).
}

在性能方面,你不需要创建一个新字符串(与 substr 不同),如果它不是以你想要的开头,你也不需要解析整个字符串。尽管您第一次使用正则表达式(您需要创建/编译它),但您会受到性能损失。

此扩展维护已编译的常规的全局每线程缓存 表达式(最多 4096 个)。 http://www.php.net/manual/en/intro.pcre.php

【讨论】:

  • 正则表达式要复杂得多,然后是 strpos 或 substr 操作,因此它会花费更多的性能,在此任务中它绝对不需要
  • @Sharpy35: 也许吧,但我不考虑性能成本,除非我发现它使系统变得太慢。避免过早的优化。此外,正则表达式功能强大得多,开发人员应该知道这一点。
  • 我没有说我不知道​​正则表达式 ;) 我只是尽可能避免使用它 :)
  • 当这是性能最差的方法时,我认为讨论“性能方面”是不公平的
  • 令我惊讶的是(至少在 PHP 7.3.6 上),这实际上似乎比 strpos 更快! (而且它只比 substr 慢一点)
【解决方案5】:

您可以使用下面的小函数检查您的字符串是否以 http 或 https 开头。

function has_prefix($string, $prefix) {
   return substr($string, 0, strlen($prefix)) == $prefix;
}

$url   = 'http://www.google.com';
echo 'the url ' . (has_prefix($url, 'http://')  ? 'does' : 'does not') . ' start with http://';
echo 'the url ' . (has_prefix($url, 'https://') ? 'does' : 'does not') . ' start with https://';

【讨论】:

  • 如果有人读过这个答案,那么三元组? true : false 是多余的,可以完全删除
猜你喜欢
  • 2014-11-28
  • 2011-05-04
  • 2012-02-09
  • 1970-01-01
  • 2010-12-30
  • 2023-01-01
  • 2019-08-24
  • 2015-04-15
  • 2012-02-06
相关资源
最近更新 更多