【问题标题】:PHP: Undefined offset: 3 - preg_match_allPHP:未定义的偏移量:3 - preg_match_all
【发布时间】:2016-04-24 23:21:50
【问题描述】:

我有来自示例的 URL 结构:

http://www.example.com/directory/some-text-a1-vs-sec-text-b2-vs-third-text-vs-last-text-c1/

我的正则表达式是:

preg_match_all("/([^\/.]+?)(?:-vs-|\.\w+$)/", $html, $matches);

预期结果:

some-text-a1
sec-text-b2
third-text
last-text-c1

我得到的结果:

some-text-a1
sec-text-b2
third-text
Notice: Undefined offset: 3 in F:\xampp\htdocs\url.php on line 41

完整代码:

$html = "http://www.example.com/directory/some-text-a1-vs-sec-text-b2-vs-third-text-vs-last-text-c1/";
preg_match_all("/([^\/.]+?)(?:-vs-|\.\w+$)/", $html, $matches);

$prvi = "some-text-a1";
$drugi = "sec-text-b2";
$treci = "third-text";
$cetvrti = "last-text-c1";

echo "URL: ".$html."<br>";

if($prvi == $matches[1][0]){echo "1st O.K. - ".$prvi." = ".$matches[1][0]."<br>";}
if($drugi == $matches[1][1]){echo "2nd O.K. - ".$drugi." = ".$matches[1][1]."<br>";}
if($treci == $matches[1][2]){echo "3rd O.K. - ".$treci." = ".$matches[1][2]."<br>";}
if($cetvrti == $matches[1][3]){echo "4th O.K. - ".$cetvrti." = ".$matches[1][3]."<br>";}

想法我错过了什么?我想结尾的斜杠 / 是我的正则表达式中的问题。

有什么想法吗?谢谢!

【问题讨论】:

  • 使用var_dump 查看您在$matches 中实际拥有的内容。 php.net/var_dump
  • array(2) { [0]=> array(3) { [0]=> string(16) "some-text-a1-vs-" [1]=> string(15 ) "sec-text-b2-vs-" [2]=> string(14) "third-text-vs-" } [1]=> array(3) { [0]=> string(12) "一些-text-a1" [1]=> string(11) "sec-text-b2" [2]=> string(10) "third-text" } }
  • 写错了,或者你期望的东西错了。
  • \w+ 应该在您的表达式中匹配什么?它会导致 URL 的最后一部分根本不匹配。 . 匹配尾部斜杠(尽管您不应该转义它),然后表达式需要在行尾之前至少有一个单词字符,其中没有,因为已经到达行尾。
  • 是的,正则表达式是错误的。 regex101.com/r/aP9eP8/1

标签: php regex url


【解决方案1】:

试试这个

(?<=vs-)(.*?)(?=-vs)|(?<=\/)([^\/]*?)(?=-vs)|(?<=vs-)(.*?)(?=\/|$)

Regex demo

解释:
(?&lt;=…):正向后视sample
( … ):捕获组sample
.:除换行符之外的任何字符@987654324 @
*: 零次或多次 sample
?: 一次或无 sample
(?=…): 正向前瞻 sample
|: 交替/或操作数sample
\:转义一个特殊字符sample
[^x]:一个不是x的字符sample
$:字符串结束或行结束取决于多行模式sample

PHP:

<?php
$re = "/(?<=vs-)(.*?)(?=-vs)|(?<=\\/)([^\\/]*?)(?=-vs)|(?<=vs-)(.*?)(?=\\/|$)/"$
$str = "http://www.example.com/directory/some-text-a1-vs-sec-text-b2-vs-third-t$

preg_match_all($re, $str, $matches);
print_r($matches[0]);

输出:

Array
(
    [0] => some-text-a1
    [1] => sec-text-b2
    [2] => third-text
    [3] => last-text-c1
)

【讨论】:

    【解决方案2】:

    这是一种不同的方法 - 使用 parse_urlexplode 函数。

    <?php
    $url = 'http://www.example.com/directory/some-text-a1-vs-sec-text-b2-vs-third-text-vs-last-text-c1/';
    
    $parsedUrl = parse_url($url);
    
    var_dump($parsedUrl);
    
    $path = explode('/',trim($parsedUrl['path'],'/'));
    
    var_dump($path);
    
    if (is_array($path) && $path[0] === 'directory') {
            if (isset($path[1])) {
                    $vs = explode('-vs-',$path[1]);
                    var_dump($vs);
            }
    }
    

    【讨论】:

    • parse_url 有第二个参数,仅获取您感兴趣的部分作为字符串。
    • 感谢explode()函数的想法!
    猜你喜欢
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    相关资源
    最近更新 更多