我尝试使用此正则表达式从字符串ad.test.com
获取值768
和"adress=ad.test.com\n port=768"
,但它不起作用:/
$res = preg_split("/^adresse=([a-z]).*port=([0-9]{3})/", $test) ;
答案 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];
关于正则表达式失败原因的说明:
.
,字符类未量化。adress
在您的字符串中,但您正在寻找正则表达式中的addresse
.
修饰符,否则s
与新行不匹配。正则表达式演示:https://regex101.com/r/3MSiDh/1/
更准确的正则表达式,不需要s
修饰符:
^adress=([a-z.]+?)\s*port=(\d{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";
}
}
}
}