使用PHP获取每两个特定字符之间的字符串

Posted

技术标签:

【中文标题】使用PHP获取每两个特定字符之间的字符串【英文标题】:Get string between every two certain characters with PHP 【发布时间】:2019-05-12 06:49:27 【问题描述】:

我有这样的字符串:

The time is over. # its mean I'm need to die. Please help me. # Ghost. I am here alone. Sorry. # help yourself.

我想获取每个 # 和点 (.) 之间的文本 所以我用这个:

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);


$parsed = trim(get_string_between($url, '#', '.'));
echo $parsed;

问题在于该函数仅返回与我的查询匹配的第一个示例。对于我选择的每个查询,我没有任何想法。

在这个示例字符串中它需要返回这个:

its mean I'm need to die

Ghost

help yourself

编辑@Nick Answer

我真正的字符串是这样的:

Text Text Text # Very good. #:* after this come example. Text Text Text #Very good number 2.

您的代码还返回了#:* 之后的字符串,我只需要这些示例: # Text Text. #Text Text.

在给定的示例中,我需要获取以下文本:

Very goodVery good number 2

【问题讨论】:

你的问题描述真的不清楚。在每个 #. 之间?这意味着您在第一个示例字符串中的匹配项将是 (space)its mean I'm need to die 对吗? 您希望第二个结果是“Ghost”还是“Ghost。我一个人在这里”?因为即使通过文本循环您的函数,您仍然会遇到所需文本内部有句点的问题。也许更好的方法是找到# 和换行符之间的文本? 不,我现在只是编辑问题以使其清楚。 @Xatenev 查看编辑 @JaredC 否,因为查询文本可以在文本中间。 所以你复制了答案here 没有自己尝试任何东西并寻求人们的帮助?我称之为懒惰。 【参考方案1】:

更新

根据 OP 编辑​​,需要更改正则表达式,以便在 # 之后立即对空格或字母字符使用正向预读,即

/#(?=[ A-Za-z])\s*([^.]*)\./

要使用编辑中的文本:

$string = "Text Text Text # Very good. #:* after this come example. Text Text Text #Very good number 2.";
preg_match_all('/#(?=[ A-Za-z])\s*([^.]*)\./', $string, $matches);
print_r($matches[1]);

输出

Array
(
    [0] => Very good
    [1] => Very good number 2
)

更新demo on rextester

原答案

您可以使用preg_match_all 来获得您想要的结果。此正则表达式在 #. 之间查找一组字符,通过使用非贪婪捕获组和捕获组两侧的 \s* 去除两端的任何空格:

$string = "The time is over. # its mean I'm need to die .
Please help me. # Ghost. I am here alone.
Sorry. # help yourself.";
preg_match_all('/#\s*([^.]*?)\s*\./', $string, $matches);
print_r($matches[1]);

输出:

Array
(
    [0] => its mean I'm need to die
    [1] => Ghost
    [2] => help yourself
)

Demo on rextester

【讨论】:

工作完美,但仅在第一个,因为我的字符串与我给定的示例不同。我现在编辑帖子。 @Ben 所以# 后面只能有空格或字母字符,对吗? 是的,完全正确。例如:# text.#text. 但不是 #:* text. @Ben 我认为我编辑的答案将解决该问题。 可以在$matches[1]上进行foreach吗?【参考方案2】:

explode、substr 和 strpos 的组合可以做到:

#分割字符串,然后使用substrstrpos得到#和第一个.之间的字符串。

<?php

$examples = [
    'The time is over. # its mean I\'m need to die.',
'Please help me. # Ghost. I am here alone.',
'Sorry. # help yourself.'];

foreach($examples as $example) 
    $exploded = explode('#', $example);
    $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));
    var_dump($substr);

在一个特定字符串的函数中:

$test = parseString('Sorry. # help yourself.');
function parseString($string) 
    $exploded = explode('#', $string);
    $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));

    return $substr;


var_dump($test);

对于字符串输入,我们必须执行一个额外的步骤,该步骤之前被\n 打破:

$stringExample = "The time is over. # its mean I'm need to die.
Please help me. # Ghost. I am here alone.
Sorry. # help yourself.";


$test2 = parseString2($stringExample);
function parseString2($string) 
    $result = [];
    $array = explode("\n", $string);

    foreach($array as $a) 
        $exploded = explode('#', $a);
        $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));    
        $result[] = $substr;
    

    return $result;

var_dump($test2);

对于没有换行符的字符串输入,一个小解析器可能如下所示:

$stringExample2 = "The time is over. # its mean I'm need to die. Please help me. # Ghost. I am here alone. Sorry. # help yourself.";


var_dump(parseString3($stringExample2));
function parseString3($stringExample)

    $result2 = [];

    $startBlock = false;

    $block = 0;
    foreach (str_split($stringExample) as $char) 
        if ($char === '#')  // Start block
            $startBlock = true;
         else if ($startBlock && $char === '.')  // End block
            $result2[$block] = trim($result2[$block]); // Remove unnecessary whitespace
            $block++;
            $startBlock = false;
         else if ($startBlock)  // Character to append to block
            if (!isset($result2[$block]))  // We have to check if the block has been started already and if not, create it as an empty string because otherwise we would get a notice when trying to append our character to it.
                $result2[$block] = '';
            
            $result2[$block] .= $char;
        

    
    return $result2;

如果您使用此代码中的任何一个,请确保真正了解正在发生的事情并使用适当的变量名,这些只是 sn-ps 的小示例。

所有示例及其输出都可以在下面的 3v4l 链接中找到

https://3v4l.org/k3TXM

【讨论】:

不是字符串数组,只是字符串 @executable ?我正在遍历 OP 中的示例。我将添加一个带有特定字符串的示例,但我不明白为什么需要它 @Xatenev 非常感谢您的帮助。正如他所说,我的问题在于没有数组的字符串 - 我尝试你过去发送的内容。 @executable 哦,我明白你的意思了。 @Xatenev 抱歉,但正如我在问题中所说,我的问题与我的示例一样的多个查询有关。我的意思是 - 超过 1 个。

以上是关于使用PHP获取每两个特定字符之间的字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在jQuery中的两个字符串之间获取url的特定部分[重复]

将PHP字符串中两个字符之间的数字相乘

获取两个字符串之间的内容 PHP

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

php正则表达式获取两个字符之间的文字

在Python中的数据框中的每一行的两个子字符串之间选择字符串