我正在处理需要将RIPE分配数据库(ftp://ftp.ripe.net/ripe/stats/membership/alloclist.txt)解析为数据库的项目。
我需要抓住每一个成员,所以我需要它来匹配xx之间的所有内容。和\ n \ nxx。其中x是任何小写字母。
以下是该文件的几行:
ad.andorpac
Servei de Telecomunicacions d'Andorra
19960627 194.158.64.0/19 ALLOCATED PA
20050104 85.94.160.0/19 ALLOCATED PA
20061117 91.187.64.0/19 ALLOCATED PA
20091124 109.111.96.0/19 ALLOCATED PA
20120925 185.4.52.0/22 ALLOCATED PA
20110722 2a02:8060::/31
ae.absl-me
Asia Broadcast Satellite Ltd (Middle East)
20110321 31.47.88.0/21 ALLOCATED PA
ae.adac
Abu Dhabi Airports Company PJSC
20120402 37.218.224.0/21 ALLOCATED PA
我不是RegEx专家,任何人都可以提供这些表达吗?
答案 0 :(得分:1)
你不需要一个非常详细的正则表达式来解析它。您可以按分隔符拆分,然后解析每个条目:
// $string contains the text
$entries = explode("\n\n", $string);
for($i=0; $i < sizeof($entries); $i+=2){
parse_header($entries[$i]));
parse_entries($entries[$i+1]);
}
“标题”就像“ad.andorpac \ nServei de Telecomunicacions(...)”所以它应该很容易解析。要解析这些条目,可以用“\ n”拆分它们,然后用正则表达式处理它们,用空格分割字段:
function parse_entry($entries){
$strings = explode("\n", $entries);
foreach($strings as $s){
preg_match("/(?P<number>\d+)\s+(?P<addr>[\d\.\/]+)\s+(?P<str1>\w+)\s+(?P<str2>\w+)/",
$s, $result);
// You can then access then the results
echo $results["addr"]; // prints "185.4.52.0/22"
}
}
这不是一个完整的答案,但应该解决你的大部分问题。您可能还需要使用trim
函数来删除匹配字符串开头/结尾的空格。
正则表达式的快速解释:
(?P<number>\d+) => matches one or more digits, and stores them in the "number" index
\s+ => matches one or more spaces and ignores them
(?P<addr>[\d\.\/]+) => matches the network address (one or more digits, dots or slashes)
\s+ => same
(?P<str1>\w+) => matches the first string ("ALLOCATED")
\s+ =>
(?P<str2>\w+) => matches the 2nd string
答案 1 :(得分:1)
类似的东西:
preg_match_all("/[a-z]{2}\..*?\n\n[a-z]{2}\./s", $text, $matches)
应该工作。
这假设您对问题的描述是准确的!如果不是,你可以期待这个正则表达式非常脆弱。
(即:发生\n\n[a-z]{2}\.
的不良实例,您希望每个匹配中包含下一个条目的前3个字符,您的记录之间将始终存在两个新行,它们将相邻,没有任何其他包括任何空格等之间的字符。)。
好吧,我猜你不会真的想要结束“xx”。作为匹配的一部分,所以替代方案是使用前瞻,例如:
preg_match_all("/[a-z]{2}\..*?\n\n(?=[a-z]{2}\.)/s", $text, $matches)