PHP 如何预匹配这个字符串?
PHP How to preg match this string?
我有一长串 IP 地址和端口。我正在尝试从类似于此的列表中预匹配端口号:
/connect=;;41.26.162.36;;192.168.0.100;;8081;;
/connect=;;98.250.16.76;;192.168.0.24;;8080;;
/connect=;;216.152.60.12;;192.168.1.103;;8090;;
/connect=;;91.11.65.110;;192.168.1.3;;8081;;
我在使用以下方法匹配全球 IP 地址时没有遇到任何问题:
preg_match_all('/connect=;;(.+?);;/', $long, $ip);
$ip = $ip[1][0];
print_r($ip);
这对我来说非常有用,但我不知道如何预匹配位于行尾的端口。
试试这个方法...
$re = "/connect=;;(.+?);;(\d{4});;/";
$str = "/connect=;;41.26.162.36;;192.168.0.100;;8081;;/connect=;;98.250.16.76;;
192.168.0.24;;8080;;/connect=;;216.152.60.12;;192.168.1.103;;8090;;/connect=;;
91.11.65.110;;192.168.1.3;;8081;;";
preg_match_all($re, $str, $matches);
解释:
/connect=;;(.+?);;(\d{4});;/g
connect=;; matches the characters connect=;; literally (case sensitive)
1st Capturing group (.+?)
.+? matches any character (except newline)
Quantifier: +? Between one and unlimited times, as few times as possible,
expanding as needed [lazy]
;; matches the characters ;; literally
2nd Capturing group (\d{4})
\d{4} match a digit [0-9]
Quantifier: {4} Exactly 4 times
;; matches the characters ;; literally
g modifier: global. All matches (don't return on first match)
稍微扩展一下上面的答案:
if (preg_match_all('/connect=;;([\d\.]+);;([\d\.]+);;(\d+);;/',
$long, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
list(,$ip1, $ip2, $port) = $match;
/* Do stuff */
echo "{$ip1} => {$ip2}:{$port}\n";
}
}
您可以在 IP 检测上更聪明一些,但如果您的样本格式正确,这应该绰绰有余。
由于您的日志将被严格可靠地格式化,您可以只扫描格式化的字符串。
https://www.php.net/manual/en/function.sscanf.php
sscanf()
不会像 preg_match_all()
那样产生不需要的全字符串匹配。
代码:(Demo)
$logs = <<<LOGS
/connect=;;41.26.162.36;;192.168.0.100;;8081;;
/connect=;;98.250.16.76;;192.168.0.24;;8080;;
/connect=;;216.152.60.12;;192.168.1.103;;8090;;
/connect=;;91.11.65.110;;192.168.1.3;;8081;;
LOGS;
foreach(explode(PHP_EOL, $logs) as $line) {
sscanf($line, "/connect=;;%[^;];;%[^;];;%d;;", $ip1, $ip2, $port);
var_export(
[$ip1, $ip2, $port]
);
echo "\n";
}
输出:
array (
0 => '41.26.162.36',
1 => '192.168.0.100',
2 => 8081,
)
array (
0 => '98.250.16.76',
1 => '192.168.0.24',
2 => 8080,
)
array (
0 => '216.152.60.12',
1 => '192.168.1.103',
2 => 8090,
)
array (
0 => '91.11.65.110',
1 => '192.168.1.3',
2 => 8081,
)
我有一长串 IP 地址和端口。我正在尝试从类似于此的列表中预匹配端口号:
/connect=;;41.26.162.36;;192.168.0.100;;8081;;
/connect=;;98.250.16.76;;192.168.0.24;;8080;;
/connect=;;216.152.60.12;;192.168.1.103;;8090;;
/connect=;;91.11.65.110;;192.168.1.3;;8081;;
我在使用以下方法匹配全球 IP 地址时没有遇到任何问题:
preg_match_all('/connect=;;(.+?);;/', $long, $ip);
$ip = $ip[1][0];
print_r($ip);
这对我来说非常有用,但我不知道如何预匹配位于行尾的端口。
试试这个方法...
$re = "/connect=;;(.+?);;(\d{4});;/";
$str = "/connect=;;41.26.162.36;;192.168.0.100;;8081;;/connect=;;98.250.16.76;;
192.168.0.24;;8080;;/connect=;;216.152.60.12;;192.168.1.103;;8090;;/connect=;;
91.11.65.110;;192.168.1.3;;8081;;";
preg_match_all($re, $str, $matches);
解释:
/connect=;;(.+?);;(\d{4});;/g
connect=;; matches the characters connect=;; literally (case sensitive)
1st Capturing group (.+?)
.+? matches any character (except newline)
Quantifier: +? Between one and unlimited times, as few times as possible,
expanding as needed [lazy]
;; matches the characters ;; literally
2nd Capturing group (\d{4})
\d{4} match a digit [0-9]
Quantifier: {4} Exactly 4 times
;; matches the characters ;; literally
g modifier: global. All matches (don't return on first match)
稍微扩展一下上面的答案:
if (preg_match_all('/connect=;;([\d\.]+);;([\d\.]+);;(\d+);;/',
$long, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
list(,$ip1, $ip2, $port) = $match;
/* Do stuff */
echo "{$ip1} => {$ip2}:{$port}\n";
}
}
您可以在 IP 检测上更聪明一些,但如果您的样本格式正确,这应该绰绰有余。
由于您的日志将被严格可靠地格式化,您可以只扫描格式化的字符串。
https://www.php.net/manual/en/function.sscanf.php
sscanf()
不会像 preg_match_all()
那样产生不需要的全字符串匹配。
代码:(Demo)
$logs = <<<LOGS
/connect=;;41.26.162.36;;192.168.0.100;;8081;;
/connect=;;98.250.16.76;;192.168.0.24;;8080;;
/connect=;;216.152.60.12;;192.168.1.103;;8090;;
/connect=;;91.11.65.110;;192.168.1.3;;8081;;
LOGS;
foreach(explode(PHP_EOL, $logs) as $line) {
sscanf($line, "/connect=;;%[^;];;%[^;];;%d;;", $ip1, $ip2, $port);
var_export(
[$ip1, $ip2, $port]
);
echo "\n";
}
输出:
array (
0 => '41.26.162.36',
1 => '192.168.0.100',
2 => 8081,
)
array (
0 => '98.250.16.76',
1 => '192.168.0.24',
2 => 8080,
)
array (
0 => '216.152.60.12',
1 => '192.168.1.103',
2 => 8090,
)
array (
0 => '91.11.65.110',
1 => '192.168.1.3',
2 => 8081,
)