如何在PHP中获取两个字符串之间的子字符串?

Nad*_*ami 125 php substring

我需要一个函数来返回两个单词(或两个字符)之间的子串.我想知道是否有一个PHP功能实现了这一点.我不想考虑正则表达式(好吧,我可以做一个,但真的不认为这是最好的方式).思考strpossubstr功能.这是一个例子:

$string = "foo I wanna a cake foo";
Run Code Online (Sandbox Code Playgroud)

我们称之为功能:$substring = getInnerSubstring($string,"foo");
它返回:"我想要一块蛋糕".

提前致谢.

更新: 嗯,到现在为止,我只能在一个字符串中得到一个字符串只有两个字,你是否允许让我走得更远,并且问我是否可以扩展使用getInnerSubstring($str,$delim)来获取delim值之间的任何字符串,例:

$string =" foo I like php foo, but foo I also like asp foo, foo I feel hero  foo";
Run Code Online (Sandbox Code Playgroud)

我得到一个类似的数组{"I like php", "I also like asp", "I feel hero"}.

Ale*_*ias 290

如果字符串不同(即:[foo]和[/ foo]),请查看Justin Cook的这篇文章.我复制下面的代码:

function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return '';
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}

$fullstring = 'this is my [tag]dog[/tag]';
$parsed = get_string_between($fullstring, '[tag]', '[/tag]');

echo $parsed; // (result = dog)
Run Code Online (Sandbox Code Playgroud)

  • 修改此func以包括开始和结束.<code> function string_between($ string,$ start,$ end,$ inclusive = false){$ string ="".$ string; $ ini = strpos($ string,$ start); if($ ini == 0)返回""; if(!$ inclusive)$ ini + = strlen($ start); $ len = strpos($ string,$ end,$ ini) - $ ini; if($ inclusive)$ len + = strlen($ end); return substr($ string,$ ini,$ len); } </ code> (7认同)
  • 是否可以扩展此功能以便它可以返回两个字符串?假设我有一个 $fullstring 的“[tag]dogs[/tag] 和 [tag]cats[/tag]”,我想要一个包含“dogs”和“cats”的数组。 (2认同)
  • @LeonardSchuetz - 然后尝试 [this answer](http://stackoverflow.com/a/27078384/2199525)。 (2认同)

nkk*_*law 61

正则表达式是要走的路:

$str = 'before-str-after';
if (preg_match('/before-(.*?)-after/', $str, $match) == 1) {
    echo $match[1];
}
Run Code Online (Sandbox Code Playgroud)

onlinePhp

  • 效果很好!对于不习惯正则表达式的人,只需添加“\”来转义特殊字符:http://sandbox.onlinephpfunctions.com/code/76dab69f60af4de53c01efb37213b78d024b23d8 (2认同)

小智 22

function getBetween($string, $start = "", $end = ""){
    if (strpos($string, $start)) { // required if $start not exist in $string
        $startCharCount = strpos($string, $start) + strlen($start);
        $firstSubStr = substr($string, $startCharCount, strlen($string));
        $endCharCount = strpos($firstSubStr, $end);
        if ($endCharCount == 0) {
            $endCharCount = strlen($firstSubStr);
        }
        return substr($firstSubStr, 0, $endCharCount);
    } else {
        return '';
    }
}
Run Code Online (Sandbox Code Playgroud)

样品用途:

echo getBetween("abc","a","c"); // returns: 'b'

echo getBetween("hello","h","o"); // returns: 'ell'

echo getBetween("World","a","r"); // returns: ''
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,你的"样本使用"段落错了.争论的顺序完全错误. (5认同)

Chr*_*ian 14

function getInnerSubstring($string,$delim){
    // "foo a foo" becomes: array(""," a ","")
    $string = explode($delim, $string, 3); // also, we only need 2 items at most
    // we check whether the 2nd is set and return it, otherwise we return an empty string
    return isset($string[1]) ? $string[1] : '';
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

var_dump(getInnerSubstring('foo Hello world foo','foo'));
// prints: string(13) " Hello world "
Run Code Online (Sandbox Code Playgroud)

如果要删除周围的空格,请使用trim.例:

var_dump(trim(getInnerSubstring('foo Hello world foo','foo')));
// prints: string(11) "Hello world"
Run Code Online (Sandbox Code Playgroud)


小智 13

function getInbetweenStrings($start, $end, $str){
    $matches = array();
    $regex = "/$start([a-zA-Z0-9_]*)$end/";
    preg_match_all($regex, $str, $matches);
    return $matches[1];
}
Run Code Online (Sandbox Code Playgroud)

例如,在下面的示例中,您需要@@之间的字符串(键)数组,其中'/'不介于两者之间

$str = "C://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@";
$str_arr = getInbetweenStrings('@@', '@@', $str);

print_r($str_arr);
Run Code Online (Sandbox Code Playgroud)

  • 当它是$ start或$ end变量时,不要忘记像"/"那样转义"/". (2认同)

rag*_*nar 8

我喜欢正则表达式解决方案,但其他人都不适合我.

如果您知道只有1个结果,您可以使用以下内容:

$between = preg_replace('/(.*)BEFORE(.*)AFTER(.*)/sm', '\2', $string);
Run Code Online (Sandbox Code Playgroud)

之前和之后更改为所需的分隔符.

另请注意,如果没有匹配,此函数将返回整个字符串.

此解决方案是多行的,但您可以根据需要使用修改器.

  • 然后我会解释你错过了什么。`m` 是一个模式修饰符,仅影响包含 `^` 或 `$` 的模式。`s` 修饰符很有意义,因为它影响模式中的 `.` 字符。“m”没有任何作用。 (2认同)

Bry*_*yce 8

两次使用strstr php函数。

$value = "This is a great day to be alive";
$value = strstr($value, "is"); //gets all text from needle on
$value = strstr($value, "be", true); //gets all text before needle
echo $value;
Run Code Online (Sandbox Code Playgroud)

输出: "is a great day to"


obl*_*lig 6

如果您使用的foo是分隔符,请查看explode()

  • 这个模糊的暗示可能是问题下的评论。 (2认同)

小智 5

<?php
  function getBetween($content,$start,$end){
    $r = explode($start, $content);
    if (isset($r[1])){
        $r = explode($end, $r[1]);
        return $r[0];
    }
    return '';
  }
?>
Run Code Online (Sandbox Code Playgroud)

例:

<?php 
  $content = "Try to find the guy in the middle with this function!";
  $start = "Try to find ";
  $end = " with this function!";
  $output = getBetween($content,$start,$end);
  echo $output;
?>
Run Code Online (Sandbox Code Playgroud)

这将返回"中间人".


Lig*_*t93 5

不是PHP专业版。但是我最近也碰到了这堵墙,这就是我想出的。

function tag_contents($string, $tag_open, $tag_close){
   foreach (explode($tag_open, $string) as $key => $value) {
       if(strpos($value, $tag_close) !== FALSE){
            $result[] = substr($value, 0, strpos($value, $tag_close));;
       }
   }
   return $result;
}

$string = "i love cute animals, like [animal]cat[/animal],
           [animal]dog[/animal] and [animal]panda[/animal]!!!";

echo "<pre>";
print_r(tag_contents($string , "[animal]" , "[/animal]"));
echo "</pre>";

//result
Array
(
    [0] => cat
    [1] => dog
    [2] => panda
)
Run Code Online (Sandbox Code Playgroud)


Qui*_*nus 5

这里的绝大多数答案都没有回答编辑过的部分,我猜它们是之前添加的。正如一个答案所提到的,它可以用正则表达式来完成。我有不同的方法。


此函数搜索 $string 并查找$start 和 $end字符串之间第一个字符串,从 $offset 位置开始。然后它更新 $offset 位置以指向结果的开始。如果 $includeDelimiters 为真,它将在结果中包含分隔符。

如果未找到 $start 或 $end 字符串,则返回 null。如果 $string、$start 或 $end 是空字符串,它也会返回 null。

function str_between(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?string
{
    if ($string === '' || $start === '' || $end === '') return null;

    $startLength = strlen($start);
    $endLength = strlen($end);

    $startPos = strpos($string, $start, $offset);
    if ($startPos === false) return null;

    $endPos = strpos($string, $end, $startPos + $startLength);
    if ($endPos === false) return null;

    $length = $endPos - $startPos + ($includeDelimiters ? $endLength : -$startLength);
    if (!$length) return '';

    $offset = $startPos + ($includeDelimiters ? 0 : $startLength);

    $result = substr($string, $offset, $length);

    return ($result !== false ? $result : null);
}
Run Code Online (Sandbox Code Playgroud)

以下函数查找两个字符串之间的所有字符串(无重叠)。它需要前面的函数,并且参数是相同的。执行后,$offset 指向最后找到的结果字符串的开头。

function str_between_all(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?array
{
    $strings = [];
    $length = strlen($string);

    while ($offset < $length)
    {
        $found = str_between($string, $start, $end, $includeDelimiters, $offset);
        if ($found === null) break;

        $strings[] = $found;
        $offset += strlen($includeDelimiters ? $found : $start . $found . $end); // move offset to the end of the newfound string
    }

    return $strings;
}
Run Code Online (Sandbox Code Playgroud)

例子:

str_between_all('foo 1 bar 2 foo 3 bar', 'foo', 'bar')[' 1 ', ' 3 '].

str_between_all('foo 1 bar 2', 'foo', 'bar')[' 1 '].

str_between_all('foo 1 foo 2 foo 3 foo', 'foo', 'foo')[' 1 ', ' 3 '].

str_between_all('foo 1 bar', 'foo', 'foo')[].


小智 5

简单、简短、甜蜜。由您决定是否进行任何增强。

function getStringBetween($str, $start, $end) 
{
    $pos1 = strpos($str, $start);
    $pos2 = strpos($str, $end);
    return substr($str, $pos1+1, $pos2-($pos1+1));
 }
Run Code Online (Sandbox Code Playgroud)