正则表达式在=后获得值

时间:2017-09-28 20:23:54

标签: php regex

我尝试使用此正则表达式从字符串ad.test.com获取值768"adress=ad.test.com\n port=768",但它不起作用:/

$res = preg_split("/^adresse=([a-z]).*port=([0-9]{3})/", $test) ; 

2 个答案:

答案 0 :(得分:2)

这应该捕获您想要的2个数据点:

^adress=([a-z.]+).*port=([0-9]{3})

您还希望将其与preg_match一起使用,而不是preg_split

preg_match('/^adress=([a-z.]+).*port=([0-9]{3})/s', 'adress=ad.test.com\n port=768', $match);
echo $match[1] . ' ' . $match[2];

演示:https://3v4l.org/Ih929

关于正则表达式失败原因的说明:

  1. 字符类缺少.,字符类未量化。
  2. adress在您的字符串中,但您正在寻找正则表达式中的addresse
  3. 除非使用.修饰符,否则
  4. s与新行不匹配。
  5. 正则表达式演示:https://regex101.com/r/3MSiDh/1/

    更准确的正则表达式,不需要s修饰符:

    ^adress=([a-z.]+?)\s*port=(\d{3})
    

    演示2:https://regex101.com/r/3MSiDh/3/

答案 1 :(得分:1)

第一次优化,接近你的表达:

preg_match('/\badress=([a-z\.]*)\s+port=(\d*)/',$string,$matches)

略微更通用。你不想匹配'badaddress',例如,\ b是什么,你可能得到超过3位数的端口等,我使用\ d而不是[0-9]。

但是这个正则表达式对输入非常严格:顺序是固定的,空格的位置是有限的,你不能有任何未知数。 要解决这个问题,我会匹配参数/值对,然后对这些对中的每一对进行操作。此外,命名匹配可以减少括号中的错误以及正则表达式的未来演变。

参数/值对匹配可以如下所示:

preg_match_all('/\b(?P<param>[^\d\s]\S*)\s*=\s*(?P<value>\S*)(?:\s|$)/m',$string,$matches)

这提供了$matches['param']$matches['value']。下面的示例将遍历此列表以查找已知参数并检查其值的有效性,以便在适当时提供一些错误消息。

下面的代码显示了包含一些测试字符串的完整代码。您可以查看here

/** Some strings to test our code */
$testStrings=[
    "adress=example.com port=464",
    "adress =example.com\nport=4645",
    "port=1  protocol=https adress= example.com",
];
/** Test for each string */
foreach($testStrings as $string) {
    print "\n\nTESTING:'".escapeshellarg($string)."'\n";

    /** First method - does not match them all */
    if(preg_match('/\badress=([a-z\.]*)\s+port=(\d*)/',$string,$matches)) {
        print "Matched {$matches[1]}:{$matches[2]}\n";
    }

    /** Second method - get param/value pairs first, then check them */
    if(preg_match_all('/\b(?P<param>[^\d\s]\S*)\s*=\s*(?P<value>\S*)(?:\s|$)/m',$string,$matches)) {
        //var_dump($matches); // Uncomment to see the raw data.
        $i=0;  // We need an index.
        foreach($matches['param'] as $param) {
            $value=$matches['value'][$i]; // Put value in local $value
            $i++;
            switch($param) { // Find parameters we know, complain if needed.
                case "adress":
                    print "ADDRESS IS $value\n";
                    break;
                case "port":
                    if(($result=preg_match('/^\d{3}$/',$value))) {
                        var_dump($result);
                        print "PORT IS $value\n";
                    } else {
                        print "PORT MUST HAVE EXACTLY 3 DIGITS - Got: $value\n";
                    }
                    break;
                default:
                    print "UNKNOWN PARAMETER $param=$value\n";
            }
        }
    }
}