【问题标题】:Parse text between 2 words解析两个单词之间的文本
【发布时间】:2013-08-14 04:23:36
【问题描述】:

当然,这已经被其他人问过了,但是我在 SO 上搜索过这里并没有找到任何东西 https://stackoverflow.com/search?q=php+parse+between+words

我有一个字符串,想要获得一个包含 2 个分隔符(2 个单词)之间的所有单词的数组。我对正则表达式没有信心,所以我最终得到了这个解决方案,但这并不合适,因为我需要得到所有符合这些要求的单词,而不仅仅是第一个。

$start_limiter = 'First';
$end_limiter = 'Second';
$haystack = $string;

# Step 1. Find the start limiter's position

$start_pos = strpos($haystack,$start_limiter);
if ($start_pos === FALSE)
{
    die("Starting limiter ".$start_limiter." not found in ".$haystack);
}

# Step 2. Find the ending limiters position, relative to the start position

$end_pos = strpos($haystack,$end_limiter,$start_pos);

if ($end_pos === FALSE)
{
    die("Ending limiter ".$end_limiter." not found in ".$haystack);
}

# Step 3. Extract the string between the starting position and ending position
# Our starting is the position of the start limiter. To find the string we must take
# the ending position of our end limiter and subtract that from the start limiter
$needle = substr($haystack, $start_pos+1, ($end_pos-1)-$start_pos);

echo "Found $needle";

我也考虑过使用explode(),但我认为正则表达式可能会更好更快。

【问题讨论】:

  • 刚回到这里,因为这个问题已经超过了 1000 次浏览。只是想知道为什么它得到了反对票:它显示了我在搜索类似问题方面的努力,并且我提供了我的代码。

标签: php regex string parsing words


【解决方案1】:

你也可以使用两个explode语句。

例如,假设您想在 y=mx^z+b 中得到“z”。获取 z:

$formula="y=mx^z+b";
$z=explode("+",explode("^",$formula)[1])[0];

首先我得到 ^:explode("^",$formula)[1]之后的所有内容

然后我得到 + 之前的所有内容:explode("+",$previousExplode)[0]

【讨论】:

  • 抱歉,刚刚读到您已经考虑过使用explode(我知道这是一个旧线程)。也许这会对其他人有所帮助。
【解决方案2】:

这允许您使用不同的参数运行相同的函数,这样您就不必一直重写这段代码。还使用您使用的 strpos。一直对我很好。

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 a long set of words that I am going to use.';

$parsed = get_string_between($fullstring, 'This', "use");

echo $parsed;

将输出:

is a long set of words that I am going to

【讨论】:

    【解决方案3】:

    我对 PHP 不太熟悉,但在我看来你可以使用类似的东西:

    if (preg_match("/(?<=First).*?(?=Second)/s", $haystack, $result))
        print_r($result[0]);
    

    (?&lt;=First) 在后面寻找 First 但不使用它,

    .*? 捕获介于FirstSecond 之间的所有内容,

    (?=Second) 向前寻找Second,但不使用它,

    末尾的s 是使点. 匹配换行符(如果有)。


    要获取所有这些分隔符之间的文本,您可以使用preg_match_all,并且可以使用循环来获取每个元素:

    if (preg_match_all("/(?<=First)(.*?)(?=Second)/s", $haystack, $result))
        for ($i = 1; count($result) > $i; $i++) {
            print_r($result[$i]);
        }
    

    【讨论】:

    • 正则表达式比我的更干净! preg_match 没有除 TRUE 或 FALSE 以外的返回值。函数的第三个参数是以数组的形式输出。
    • @phpisuber01 哦,好的,谢谢你的信息。 :) 那我会编辑它。
    • 感谢您的代码,但它没有按预期工作。如果我有多个起始词和结束词,它只会解析第一个词。假设 $start = "A"; $end = "B";如果我有 $subject = "A Hello B . A How B - A are B , A youB";它只会返回“Hello”,而不是我想要 $match = array ("Hello" "How" "Are" "You");
    • @Giorgio 好吧,如果你想找到所有你必须使用的人preg_match_all。您在问题中使用的方法指出只有一个starting_pos 和一个end_pos,这就是为什么我使用preg_match... 之后,您可以运行一个循环来检查数组的每个元素.我编辑了代码。
    【解决方案4】:

    不确定结果是否会比您的代码更快,但您可以使用正则表达式:

    $pattern = '~(?<=' . preg_quote($start, '~') 
             . ').+?(?=' . preg_quote($end, '~') . ')~si';
    if (preg_match($pattern, $subject, $match))
        print_r($match[0]);
    

    我使用 preg_quote 转义所有在正则表达式中具有特殊含义的字符(如+*|()[]{}.? 和模式分隔符~

    (?&lt;=..) 是一个lookbehind 断言,它在您要查找的内容之前检查子字符串。
    (?=..) 是一个lookahead 断言(之后也是如此)
    .+? 表示所有字符一次或多次但可能性较小(问号使量词变得懒惰)

    s 允许点匹配换行符(不是默认行为)
    i 使搜索不区分大小写(如果不需要,可以将其删除)

    【讨论】:

    • 感谢您的代码,但它没有按预期工作。如果我有多个起始词和结束词,它只会解析第一个词。假设 $start = "A"; $end = "B";如果我有 $subject = "A Hello B . A How B - A are B , A youB";它只会返回“Hello”,而不是我想要 $match = array ("Hello" "How" "Are" "You");
    • @Giorgio:如果您想要所有结果,请将preg_match 替换为preg_match_all
    【解决方案5】:

    这是一个简单的示例,用于查找字符串 $t 的单词 'mega' 和 'yo' 之间的所有内容。

    PHP 示例

    $t = "I am super mega awesome-sauce, yo!";
    
    $arr = [];
    preg_match("/mega\ (.*?)\ yo/ims", $t, $arr);
    
    echo $arr[1];
    

    PHP 输出

    awesome-sauce,
    

    【讨论】:

    • 感谢您的代码,但它没有按预期工作。如果我有多个起始词和结束词,它只会解析第一个词。假设 $start = "A"; $end = "B";如果我有 $subject = "A Hello B . A How B - A are B , A youB";它只会返回“Hello”,而不是我想要 $match = array ("Hello" "How" "Are" "You");
    猜你喜欢
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    相关资源
    最近更新 更多