解析2个单词之间的文本

时间:2013-08-12 18:29:11

标签: php regex string parsing words

可以肯定的是,其他人已经问过这个问题,不过我在这里搜索了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(),但我认为正则表达式可以更好更快。

5 个答案:

答案 0 :(得分:8)

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

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

(?<=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]);
    }

答案 1 :(得分:3)

不确定结果会比您的代码更快,但您可以使用正则表达式执行此操作:

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

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

(?<=..)是一个后视断言,它在你想要找到之前检查一个子串 (?=..)是一个先行断言(后来同样的事)
.+?表示所有字符一次或多次,但可能性较小(问号使量词变得懒惰)

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

答案 2 :(得分:3)

这允许您使用不同的参数运行相同的函数,这样您就不必一直重写这段代码。也使用你使用的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 :(得分:1)

这是一个简单的例子,用于查找字符串$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,

答案 4 :(得分:0)

您还可以使用两个爆炸声明。

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

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

首先我得到^:explode("^",$formula)[1]

之后的所有内容

然后我在+ explode("+",$previousExplode)[0]

之前获得了所有内容