解析一个复杂的两个文件
Parsing a complicated two files
文件 1 值:
....
Group 2012_fln
{
vnum 103
Type mixed
1 1167 1 2
2 7731 1 2
3 3561 1 2
4 8613 1 3
}
Group 7612_edb
{
vnum 104
Type other
1 6312 1 90
2 5241 5 45
....
文件 2 值:
....
1167 ºÎÈ°Àı´Ş°¿
7731 ÀÌÆÄÀÇ
3561 »¡°£»ö
....
所有值均已使用制表符分隔。顺便说一下,这两个文件中都有数千个值。
所以这是我的问题:
我需要检查文件 1 的值。文件 2 中是否存在。
如果文件 2 的值中不存在 1167 或 7731 或 3561 或 8613 值。
我需要在每个小组中都这样做。如果不存在,我需要一个错误回显,比如;在组 xxx 中,xxx vnum 不存在。并继续到文件 1 的结尾。
我想爆了,但是文件1里面的语法太多了,像Group, { }, vnum, type等等。我知道,这很复杂,所以我写在这里。
我可以像这样解析我的文件 2 值:
$line = trim($line);
$token = explode("\t", $line);
if ("" == $token[0] or "VNUM" == $token[0])
continue;
$vnum = $token[0];
$entry_name = $token[1];
所以,我真的需要很大的帮助,我在这个问题上度过了最后两天......我希望,我解释得当。
我建议使用正则表达式来解析您的数据,因为看起来每一行都遵循特定的格式。对于文件一,您可以设置一个表达式,如
^\t(\d+)\t(\d+)\t(\d+)\t(\d+)
这表示匹配一个制表符,后跟至少一个数字字符,四次。任何匹配的行将是您关心的行。从那里,您对第二组感兴趣,或 </code></p>
<p>对于文件二,您可能需要 </p>
<pre><code>^(\d+).*
这表示,至少匹配该行开头的一位数字,然后是其他任何数字。因此,您关心第一个(也是唯一一个)分组,</code>.</p>
<p>从第一个文件或第二个文件构造一个数字映射,然后迭代另一个文件中的匹配项并对照该映射进行检查。</p>
<p>由于您使用的是 php,因此您可以使用 <code>preg_match
作为正则表达式 http://php.net/manual/en/function.preg-match.php
如果您只需要第二列,并且所有需要值的行的格式都相同,请使用 file_get_contents($file1)
将文件加载到字符串中并匹配该模式(4 个数字分隔按空格)。
类似于:
preg_match_all('/^\s*\d+\s+(\d+)\s+\d+\s+\d+\s*$/m', $data, $matches);
这会将 $matches
设置为如下数组:
Array
(
[0] => Array
(
[0] => 1 1167 1 2
[1] => 2 7731 1 2
[2] => 3 3561 1 2
[3] => 4 8613 1 3
[4] => 1 6312 1 90
[5] => 2 5241 5 45
)
[1] => Array
(
[0] => 1167
[1] => 7731
[2] => 3561
[3] => 8613
[4] => 6312
[5] => 5241
)
)
$matches[1]
将是第二列中所有值的数组。您可以 foreach 循环遍历 $matches[1]
比较以查看该值是否在第二个文件中。我建议首先加载第二个文件并生成一个索引,这样当你遍历匹配时你可以只检查 array_key_exists($value, $file2Index)
.
示例,每个请求:
<?php
//read the first file in as a string
$file1 = file_get_contents("/path/to/file1");
//read the second file in as an array
$file2 = file("/path/to/file2");
//index from file2 that we are going to build
$file2Index = array();
foreach($file2 as $line){
//split the line
$line = explode("\t", $line, 2);
//validate the line, should be only 2 values after explode and first should be a number
if(count($line) == 2 && is_numeric($line[0])){
//add to index
$file2Index[$line[0]] = $line[1];
}
}
//now get all the values from file1 that we want (second column)
preg_match_all('/^\s*\d+\s*(\d+)\s*\d+\s*\d+\s*$/m', $data, $matches);
$file1Values = array_unique($matches[1]);
//loop over the matches from column 2
foreach($file1Values as $value){
//check if the key doesn't exist
if(!isset($file2Index[$value])){
//echo error message
echo "Value {$value} does not exist in file2<br>";
}
}
文件 1 值:
....
Group 2012_fln
{
vnum 103
Type mixed
1 1167 1 2
2 7731 1 2
3 3561 1 2
4 8613 1 3
}
Group 7612_edb
{
vnum 104
Type other
1 6312 1 90
2 5241 5 45
....
文件 2 值:
....
1167 ºÎÈ°Àı´Ş°¿
7731 ÀÌÆÄÀÇ
3561 »¡°£»ö
....
所有值均已使用制表符分隔。顺便说一下,这两个文件中都有数千个值。
所以这是我的问题:
我需要检查文件 1 的值。文件 2 中是否存在。 如果文件 2 的值中不存在 1167 或 7731 或 3561 或 8613 值。
我需要在每个小组中都这样做。如果不存在,我需要一个错误回显,比如;在组 xxx 中,xxx vnum 不存在。并继续到文件 1 的结尾。
我想爆了,但是文件1里面的语法太多了,像Group, { }, vnum, type等等。我知道,这很复杂,所以我写在这里。
我可以像这样解析我的文件 2 值:
$line = trim($line);
$token = explode("\t", $line);
if ("" == $token[0] or "VNUM" == $token[0])
continue;
$vnum = $token[0];
$entry_name = $token[1];
所以,我真的需要很大的帮助,我在这个问题上度过了最后两天......我希望,我解释得当。
我建议使用正则表达式来解析您的数据,因为看起来每一行都遵循特定的格式。对于文件一,您可以设置一个表达式,如
^\t(\d+)\t(\d+)\t(\d+)\t(\d+)
这表示匹配一个制表符,后跟至少一个数字字符,四次。任何匹配的行将是您关心的行。从那里,您对第二组感兴趣,或 </code></p>
<p>对于文件二,您可能需要 </p>
<pre><code>^(\d+).*
这表示,至少匹配该行开头的一位数字,然后是其他任何数字。因此,您关心第一个(也是唯一一个)分组,</code>.</p>
<p>从第一个文件或第二个文件构造一个数字映射,然后迭代另一个文件中的匹配项并对照该映射进行检查。</p>
<p>由于您使用的是 php,因此您可以使用 <code>preg_match
作为正则表达式 http://php.net/manual/en/function.preg-match.php
如果您只需要第二列,并且所有需要值的行的格式都相同,请使用 file_get_contents($file1)
将文件加载到字符串中并匹配该模式(4 个数字分隔按空格)。
类似于:
preg_match_all('/^\s*\d+\s+(\d+)\s+\d+\s+\d+\s*$/m', $data, $matches);
这会将 $matches
设置为如下数组:
Array
(
[0] => Array
(
[0] => 1 1167 1 2
[1] => 2 7731 1 2
[2] => 3 3561 1 2
[3] => 4 8613 1 3
[4] => 1 6312 1 90
[5] => 2 5241 5 45
)
[1] => Array
(
[0] => 1167
[1] => 7731
[2] => 3561
[3] => 8613
[4] => 6312
[5] => 5241
)
)
$matches[1]
将是第二列中所有值的数组。您可以 foreach 循环遍历 $matches[1]
比较以查看该值是否在第二个文件中。我建议首先加载第二个文件并生成一个索引,这样当你遍历匹配时你可以只检查 array_key_exists($value, $file2Index)
.
示例,每个请求:
<?php
//read the first file in as a string
$file1 = file_get_contents("/path/to/file1");
//read the second file in as an array
$file2 = file("/path/to/file2");
//index from file2 that we are going to build
$file2Index = array();
foreach($file2 as $line){
//split the line
$line = explode("\t", $line, 2);
//validate the line, should be only 2 values after explode and first should be a number
if(count($line) == 2 && is_numeric($line[0])){
//add to index
$file2Index[$line[0]] = $line[1];
}
}
//now get all the values from file1 that we want (second column)
preg_match_all('/^\s*\d+\s*(\d+)\s*\d+\s*\d+\s*$/m', $data, $matches);
$file1Values = array_unique($matches[1]);
//loop over the matches from column 2
foreach($file1Values as $value){
//check if the key doesn't exist
if(!isset($file2Index[$value])){
//echo error message
echo "Value {$value} does not exist in file2<br>";
}
}