获取 CSV 文件中的选项子字符串
Get option substring in CSV file
我需要解析一个 csv 文件以从每一行中获取一些信息(公司代码、公司描述、国家/地区),我在 PHP 中使用 preg_match 来解析文件,但我在某些行上遇到了麻烦。
csv 文件的某些行下方
"ASTA","Aerospace Technologies of Australia Pty Ltd (Australia)"
"ATAC"," American Tactical Aircraft Consultants (United States)"
"ATEC"," ATEC vos (Czech Republic)"
"ATG","Aviation Technology Group Inc (United States)"
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
"ATR","GIE Avions de Transport Régional (France/Italy)"
"AUSTER","Auster Aircraft Ltd (United Kingdom)"
"AUSTFLIGHT","Austflight ULA Pty Ltd (Australia)"
"AUSTRALIAN AEROSPACE","Australian Aerospace Pty Ltd (Australia)"
"AUSTRALITE","Australite Inc (United States)"
"AUTOGYRO","AutoGyro Europe GmbH (Germany)"
"AVANTAGE","OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)"
"AVCRAFT","AvCraft Aviation LLC (United States)"
"AVEKO","Aveko sro (Czech Republic)"
"AVIA (1)","Azionari Vercellese Industrie Aeronautiche (Italy)"
"AVIA (2)","Avia-Zavody Jirího Dimitrova (Czech Republic)"
PHPpreg_match代码如下
preg_match('#^(.+?)\s\((.+?)\)$#',$string,$matches);
该代码适用于如下行:
"ASSO AEREI","Asso Aerei Srl (Italy)"
在上面的示例中,我成功地将三个数据放入 matches 数组中...但是有以下行
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
我得到,作为公司描述:
Atlas Aircraft Corporation of South Africa
作为国家/地区:
Pty) Ltd (South Africa
它们应该是:
Atlas Aircraft Corporation of South Africa (Pty) Ltd
和
South Africa
另一个让我抓狂的问题是:当行不包括国家时,如下一行
"AERFER-AERMACCHI","see AERFER and AERMACCHI"
我得到一个空的公司描述数组。
对修复正则表达式模式有什么帮助吗?
非常感谢任何帮助
最好使用 fgetcsv() 函数而不是 preg_match。
$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));
fclose($file);
你可以在这里找到这个函数的参考fgetcsv()
我猜这个表达式可能有效:
(.*)\s*\((.*?)\)|(.*)
它使用
通过 ()
收集我们想要的数据
(.*)\s*\((.*?)\)
其他人没有,使用
(.*)
Demo
测试
$re = '/(.*)\s*\((.*?)\)|(.*)/m';
$str = 'Aerospace Technologies of Australia Pty Ltd (Australia)
American Tactical Aircraft Consultants (United States)
ATEC vos (Czech Republic)
Aviation Technology Group Inc (United States)
Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)
GIE Avions de Transport Régional (France/Italy)
Auster Aircraft Ltd (United Kingdom)
Austflight ULA Pty Ltd (Australia)
Australian Aerospace Pty Ltd (Australia)
Australite Inc (United States)
AutoGyro Europe GmbH (Germany)
OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)
AvCraft Aviation LLC (United States)
Aveko sro (Czech Republic)
Azionari Vercellese Industrie Aeronautiche (Italy)
Avia-Zavody Jirího Dimitrova (Czech Republic)
see AERFER and AERMACCHI';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);
这个正则表达式捕获了所有选项:
"/^(.*?)(\(([^(]*?)\))?$/"
我尝试了以下代码:
$matches=array();
$re = "/^(.*?)(\(([^(]*?)\))?$/";
preg_match($re, $string, $matches);
foreach( $matches as $match ){
echo $match."\n";
}
当 运行 与:
$string = "Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)";
输出为:
Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)
Atlas Aircraft Corporation of South Africa (Pty) Ltd
(South Africa)
South Africa
当 运行 和
$string = "see AERFER and AERMACCHI"
输出为:
see AERFER and AERMACCHI
see AERFER and AERMACCHI
因此您在 $matches[1]
中获得公司描述,在 $matches[3]
中获得国家/地区
$csv = <<<'EOD'
"ASTA","Aerospace Technologies of Australia Pty Ltd (Australia)"
"ATAC"," American Tactical Aircraft Consultants (United States)"
"ATEC"," ATEC vos (Czech Republic)"
"ATG","Aviation Technology Group Inc (United States)"
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
"ATR","GIE Avions de Transport Régional (France/Italy)"
"AUSTER","Auster Aircraft Ltd (United Kingdom)"
"AUSTFLIGHT","Austflight ULA Pty Ltd (Australia)"
"AUSTRALIAN AEROSPACE","Australian Aerospace Pty Ltd (Australia)"
"AUSTRALITE","Australite Inc (United States)"
"AUTOGYRO","AutoGyro Europe GmbH (Germany)"
"AVANTAGE","OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)"
"AVCRAFT","AvCraft Aviation LLC (United States)"
"AVEKO","Aveko sro (Czech Republic)"
"AVIA (1)","Azionari Vercellese Industrie Aeronautiche (Italy)"
"AVIA (2)","Avia-Zavody Jirího Dimitrova (Czech Republic)"
"AERFER-AERMACCHI","see AERFER and AERMACCHI"
EOD;
$url = 'data:text/plain,' . urlencode($csv);
if ( false !== $handle = fopen($url, "r") ) {
while ( false !== $data = fgetcsv($handle) ) {
if ( preg_match('~(\S.*?)(?|\h*\(([^)]*)\)|())\h*$~', $data[1], $m) )
printf("%-70s\t%s\n", $m[1], $m[2]);
}
}
模式解释:
你的问题有两点很重要:
- 国家可以是可选的
- 描述也可以包含括号
这就是为什么我在描述部分 (\S.*?)
使用了 non-greedy 量词。这样,即使存在国家/地区名称,描述子模式也被迫停在左括号处(仅当这个位于字符串末尾时)。
开头的\S
这里只是为了trim左边的描述部分。这也是该模式不使用 ^
锚点的原因。 \h*
之一将 trim 它放在右边(由于 non-greedy 量词也是如此)。
关于国家部分:我没有使用像 (?:\h*\(([^)]*)\))?
这样的可选非捕获组,而是选择使用 branch reset group (?|... (...) ... | ... (...) ...)
来确保捕获组 2 存在,即使如果国家不存在。在这种组中,捕获组在每个分支中具有相同的编号:
(?|
\h* \( ([^)]*) \) # the country name is present and captured in group 2
| # OR
() # the capture group 2 contains an empty string
)
我需要解析一个 csv 文件以从每一行中获取一些信息(公司代码、公司描述、国家/地区),我在 PHP 中使用 preg_match 来解析文件,但我在某些行上遇到了麻烦。
csv 文件的某些行下方
"ASTA","Aerospace Technologies of Australia Pty Ltd (Australia)"
"ATAC"," American Tactical Aircraft Consultants (United States)"
"ATEC"," ATEC vos (Czech Republic)"
"ATG","Aviation Technology Group Inc (United States)"
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
"ATR","GIE Avions de Transport Régional (France/Italy)"
"AUSTER","Auster Aircraft Ltd (United Kingdom)"
"AUSTFLIGHT","Austflight ULA Pty Ltd (Australia)"
"AUSTRALIAN AEROSPACE","Australian Aerospace Pty Ltd (Australia)"
"AUSTRALITE","Australite Inc (United States)"
"AUTOGYRO","AutoGyro Europe GmbH (Germany)"
"AVANTAGE","OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)"
"AVCRAFT","AvCraft Aviation LLC (United States)"
"AVEKO","Aveko sro (Czech Republic)"
"AVIA (1)","Azionari Vercellese Industrie Aeronautiche (Italy)"
"AVIA (2)","Avia-Zavody Jirího Dimitrova (Czech Republic)"
PHPpreg_match代码如下
preg_match('#^(.+?)\s\((.+?)\)$#',$string,$matches);
该代码适用于如下行:
"ASSO AEREI","Asso Aerei Srl (Italy)"
在上面的示例中,我成功地将三个数据放入 matches 数组中...但是有以下行
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
我得到,作为公司描述:
Atlas Aircraft Corporation of South Africa
作为国家/地区:
Pty) Ltd (South Africa
它们应该是:
Atlas Aircraft Corporation of South Africa (Pty) Ltd
和
South Africa
另一个让我抓狂的问题是:当行不包括国家时,如下一行
"AERFER-AERMACCHI","see AERFER and AERMACCHI"
我得到一个空的公司描述数组。
对修复正则表达式模式有什么帮助吗? 非常感谢任何帮助
最好使用 fgetcsv() 函数而不是 preg_match。
$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));
fclose($file);
你可以在这里找到这个函数的参考fgetcsv()
我猜这个表达式可能有效:
(.*)\s*\((.*?)\)|(.*)
它使用
通过()
收集我们想要的数据
(.*)\s*\((.*?)\)
其他人没有,使用
(.*)
Demo
测试
$re = '/(.*)\s*\((.*?)\)|(.*)/m';
$str = 'Aerospace Technologies of Australia Pty Ltd (Australia)
American Tactical Aircraft Consultants (United States)
ATEC vos (Czech Republic)
Aviation Technology Group Inc (United States)
Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)
GIE Avions de Transport Régional (France/Italy)
Auster Aircraft Ltd (United Kingdom)
Austflight ULA Pty Ltd (Australia)
Australian Aerospace Pty Ltd (Australia)
Australite Inc (United States)
AutoGyro Europe GmbH (Germany)
OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)
AvCraft Aviation LLC (United States)
Aveko sro (Czech Republic)
Azionari Vercellese Industrie Aeronautiche (Italy)
Avia-Zavody Jirího Dimitrova (Czech Republic)
see AERFER and AERMACCHI';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);
这个正则表达式捕获了所有选项:
"/^(.*?)(\(([^(]*?)\))?$/"
我尝试了以下代码:
$matches=array();
$re = "/^(.*?)(\(([^(]*?)\))?$/";
preg_match($re, $string, $matches);
foreach( $matches as $match ){
echo $match."\n";
}
当 运行 与:
$string = "Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)";
输出为:
Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)
Atlas Aircraft Corporation of South Africa (Pty) Ltd
(South Africa)
South Africa
当 运行 和
$string = "see AERFER and AERMACCHI"
输出为:
see AERFER and AERMACCHI
see AERFER and AERMACCHI
因此您在 $matches[1]
中获得公司描述,在 $matches[3]
$csv = <<<'EOD'
"ASTA","Aerospace Technologies of Australia Pty Ltd (Australia)"
"ATAC"," American Tactical Aircraft Consultants (United States)"
"ATEC"," ATEC vos (Czech Republic)"
"ATG","Aviation Technology Group Inc (United States)"
"ATLAS","Atlas Aircraft Corporation of South Africa (Pty) Ltd (South Africa)"
"ATR","GIE Avions de Transport Régional (France/Italy)"
"AUSTER","Auster Aircraft Ltd (United Kingdom)"
"AUSTFLIGHT","Austflight ULA Pty Ltd (Australia)"
"AUSTRALIAN AEROSPACE","Australian Aerospace Pty Ltd (Australia)"
"AUSTRALITE","Australite Inc (United States)"
"AUTOGYRO","AutoGyro Europe GmbH (Germany)"
"AVANTAGE","OOO Samoletstroitelynyi Kompaniya Avantazh (Russia)"
"AVCRAFT","AvCraft Aviation LLC (United States)"
"AVEKO","Aveko sro (Czech Republic)"
"AVIA (1)","Azionari Vercellese Industrie Aeronautiche (Italy)"
"AVIA (2)","Avia-Zavody Jirího Dimitrova (Czech Republic)"
"AERFER-AERMACCHI","see AERFER and AERMACCHI"
EOD;
$url = 'data:text/plain,' . urlencode($csv);
if ( false !== $handle = fopen($url, "r") ) {
while ( false !== $data = fgetcsv($handle) ) {
if ( preg_match('~(\S.*?)(?|\h*\(([^)]*)\)|())\h*$~', $data[1], $m) )
printf("%-70s\t%s\n", $m[1], $m[2]);
}
}
模式解释:
你的问题有两点很重要:
- 国家可以是可选的
- 描述也可以包含括号
这就是为什么我在描述部分 (\S.*?)
使用了 non-greedy 量词。这样,即使存在国家/地区名称,描述子模式也被迫停在左括号处(仅当这个位于字符串末尾时)。
开头的\S
这里只是为了trim左边的描述部分。这也是该模式不使用 ^
锚点的原因。 \h*
之一将 trim 它放在右边(由于 non-greedy 量词也是如此)。
关于国家部分:我没有使用像 (?:\h*\(([^)]*)\))?
这样的可选非捕获组,而是选择使用 branch reset group (?|... (...) ... | ... (...) ...)
来确保捕获组 2 存在,即使如果国家不存在。在这种组中,捕获组在每个分支中具有相同的编号:
(?|
\h* \( ([^)]*) \) # the country name is present and captured in group 2
| # OR
() # the capture group 2 contains an empty string
)