更新
我突然意识到,在多记录场景中,在记录循环之外构建 $repl 会表现得更好。这是 2 字节关键字版本:
$inrecs = file_get_contents('input');
$inrecs = str_replace( PHP_EOL, " ", $inrecs );
$keys = array( 'HD', 'BY', 'PD', 'LP', 'TD' );
$split = chr(255);
$repl = explode( ',', $split . implode( ','.$split, $keys ) );
$inrecs = explode( 'HD ', $inrecs );
array_shift( $inrecs );
$records = array();
foreach( $inrecs as $inrec ) $records[] = parseRecord( $keys, $repl, 'HD '.$inrec );
function parseRecord( $keys, $repl, $rec ) {
$split = chr(255);
$lines = explode( $split, str_replace( $keys, $repl, $rec ) );
array_shift( $lines );
$out = array();
foreach ( $lines as $line ) $out[ substr( $line, 0, 2 ) ] = trim( substr( $line, 3 ) );
return $out;
}
基准(感谢@jgb):
Answer 1 by: hek2mgl 6.783 seconds (regexp)
Answer 2 by: Emo Mosley 4.738 seconds
Answer 3 by: anubhava 6.299 seconds (regexp)
Answer 4 by: jgb 2.47 seconds
Answer 5 by: gwc 3.589 seconds (eval)
Answer 6 by: gwc 1.871 seconds
这是多个输入记录的另一个答案(假设每个记录以“HD”开头)并支持 2 字节、2 或 3 字节或可变长度关键字。
$inrecs = file_get_contents('input');
$inrecs = str_replace( PHP_EOL, " ", $inrecs );
$keys = array( 'HD', 'BY', 'PD', 'LP', 'TD' );
$inrecs = explode( 'HD ', $inrecs );
array_shift( $inrecs );
$records = array();
foreach( $inrecs as $inrec ) $records[] = parseRecord( $keys, 'HD '.$inrec );
使用 2 字节关键字解析记录:
function parseRecord( $keys, $rec ) {
$split = chr(255);
$repl = explode( ',', $split . implode( ','.$split, $keys ) );
$lines = explode( $split, str_replace( $keys, $repl, $rec ) );
array_shift( $lines );
$out = array();
foreach ( $lines as $line ) $out[ substr( $line, 0, 2 ) ] = trim( substr( $line, 3 ) );
return $out;
}
使用 2 或 3 字节关键字解析记录(假设键和内容之间有空格或 PHP_EOL):
function parseRecord( $keys, $rec ) {
$split = chr(255);
$repl = explode( ',', $split . implode( ','.$split, $keys ) );
$lines = explode( $split, str_replace( $keys, $repl, $rec ) );
array_shift( $lines );
$out = array();
foreach ( $lines as $line ) $out[ trim( substr( $line, 0, 3 ) ) ] = trim( substr( $line, 3 ) );
return $out;
}
使用可变长度关键字解析记录(假设键和内容之间有空格或 PHP_EOL):
function parseRecord( $keys, $rec ) {
$split = chr(255);
$repl = explode( ',', $split . implode( ','.$split, $keys ) );
$lines = explode( $split, str_replace( $keys, $repl, $rec ) );
array_shift( $lines );
$out = array();
foreach ( $lines as $line ) {
$keylen = strpos( $line.' ', ' ' );
$out[ trim( substr( $line, 0, $keylen ) ) ] = trim( substr( $line, $keylen+1 ) );
}
return $out;
}
期望上面的每个 parseRecord 函数的性能都会比它的前任差一点。
结果:
Array
(
[0] => Array
(
[HD] => Alcoa Earnings Soar; Outlook Stays Upbeat
[BY] => By James R. Hagerty and Matthew Day
[PD] => 12 July 2011
[LP] => Alcoa Inc.'s profit more than doubled in the second quarter. The giant aluminum producer managed to meet analysts' forecasts. However, profits wereless than expected
[TD] => Licence this article via our website: http://example.com
)
)