Grep PHP中大括号内的所有内容
我得到了一个需要解析并插入到DB中的文件(注意:它不是json文件),因此大括号内以#TRANS开头的行应该属于上面以#VER开头的行。我想我应该使用preg_match或preg_match,但不确定正则表达式应该是什么Grep PHP中大括号内的所有内容,php,preg-match-all,Php,Preg Match All,我得到了一个需要解析并插入到DB中的文件(注意:它不是json文件),因此大括号内以#TRANS开头的行应该属于上面以#VER开头的行。我想我应该使用preg_match或preg_match,但不确定正则表达式应该是什么 #VER 1 5 20170128 { #TRANS 8000 {} 4016.00 20170128 "something" #TRANS 1100 {} -4016.00 20170128 "something" } #VER 1 6 20170128 {
#VER 1 5 20170128
{
#TRANS 8000 {} 4016.00 20170128 "something"
#TRANS 1100 {} -4016.00 20170128 "something"
}
#VER 1 6 20170128
{
#TRANS 8010 {} 5016.00 20170128 "something else"
#TRANS 1130 {} -5016.00 20170128 "something else"
}
我会把它们分成两张桌子,我可以分多个步骤,而不是一次完成。因此,首先我将插入VER行,然后在大括号内获得正下方的TRANS行,并循环找到的行并解析它们
下面是该文件第一个示例中DB的外观示例:
Table VER:
ID | VER_DATE | (some other stuff)
5 | 20170128 | ...
Table TRANS:
ID | VER_ID | SERIAL | VALUE | DATE
1 | 5 | 8000 | 4016 | 20170128
1 | 5 | 1100 | -4016 | 20170128
嗯,如果您不需要支持复杂的语法,并且它是一次性转换,那么您可以使用
fopen
和fgets
非常轻松地进行转换:
如果您不需要支持复杂的语法,而且只需要一次转换,那么您可以使用fopen
和fgets
轻松完成转换:
您可以通过解析和处理每一行来采用某种编译器方法。它能够处理格式不正确的数据
class ParserException extends Exception {
public $line;
function __construct($message, $line) {
parent::__construct($message);
$this->line = $line;
}
}
class Parser {
const Top = 1;
const InBlock = 2;
const Ver = 4;
const Noop = 6;
public $ver = null;
function parse($input) {
$lines = explode("\n", $input);
$state = self::Top;
$this->line = 1;
try {
foreach($lines as $line) {
// echo "$line\n";
switch($state) {
case self::Top:
if ( preg_match('/^#VER (\d) (\d) ([0-9]+)/', $line, $matches) ) {
$this->emitVer($matches);
$state = self::Ver;
}
else {
throw new ParserException("VER not found", $this->line);
}
break;
case self::Ver:
if ( substr(trim($line), 0, 1) == '{' ) {
$state = self::InBlock;
}
else {
throw new ParserException("Expected { ", $this->line);
}
break;
case self::InBlock:
$trimline = trim($line);
// echo ">>> $trimline\n";
// #TRANS 8000 {} 4016.00 20170128 "something"
if ( preg_match('/^#TRANS ([0-9]+) \{\} ([0-9.-]+) ([0-9]+) "(.*)"/', $trimline, $matches) ) {
$this->emitTrans($matches);
} elseif ( substr($trimline, 0, 1) == '}' ) {
$state = self::Top;
}
else {
throw new ParserException("Expected TRANS or } ", $this->line);
}
break;
default:
// unknown state
throw new ParserException("Unexpected error ", $this->line);
break;
}
$this->line++;
}
}
catch(ParserException $e) {
echo "Parser error. " . $e->getMessage() . ' Line ' . $e->line . PHP_EOL;
}
}
function emitVer($ver) {
echo sprintf("id %s version date %s\n", $ver[2], $ver[3]);
$this->ver = ['id' => $ver[2], 'date' => $ver[3]]; // remember the version
}
function emitTrans($trans) {
echo sprintf("Trans ver-id = %s serial = %s value = %s date = %s\n", $this->ver['id'], $trans[1], $trans[2], $trans[3], $trans[4]);
}
function outr($x) {
print_r($x);
echo "\n";
}
}
$p = new Parser;
$p->parse('#VER 1 5 20170128
{
#TRANS 8000 {} 4016.00 20170128 "something"
#TRANS 1100 {} -4016.00 20170128 "something"
}
#VER 1 6 20170128
{
#TRANS 8010 {} 5016.00 20170128 "something else"
#TRANS 1130 {} -5016.00 20170128 "something else"
}');
您可以通过解析和处理每一行来采用某种编译器方法。它能够处理格式不正确的数据
class ParserException extends Exception {
public $line;
function __construct($message, $line) {
parent::__construct($message);
$this->line = $line;
}
}
class Parser {
const Top = 1;
const InBlock = 2;
const Ver = 4;
const Noop = 6;
public $ver = null;
function parse($input) {
$lines = explode("\n", $input);
$state = self::Top;
$this->line = 1;
try {
foreach($lines as $line) {
// echo "$line\n";
switch($state) {
case self::Top:
if ( preg_match('/^#VER (\d) (\d) ([0-9]+)/', $line, $matches) ) {
$this->emitVer($matches);
$state = self::Ver;
}
else {
throw new ParserException("VER not found", $this->line);
}
break;
case self::Ver:
if ( substr(trim($line), 0, 1) == '{' ) {
$state = self::InBlock;
}
else {
throw new ParserException("Expected { ", $this->line);
}
break;
case self::InBlock:
$trimline = trim($line);
// echo ">>> $trimline\n";
// #TRANS 8000 {} 4016.00 20170128 "something"
if ( preg_match('/^#TRANS ([0-9]+) \{\} ([0-9.-]+) ([0-9]+) "(.*)"/', $trimline, $matches) ) {
$this->emitTrans($matches);
} elseif ( substr($trimline, 0, 1) == '}' ) {
$state = self::Top;
}
else {
throw new ParserException("Expected TRANS or } ", $this->line);
}
break;
default:
// unknown state
throw new ParserException("Unexpected error ", $this->line);
break;
}
$this->line++;
}
}
catch(ParserException $e) {
echo "Parser error. " . $e->getMessage() . ' Line ' . $e->line . PHP_EOL;
}
}
function emitVer($ver) {
echo sprintf("id %s version date %s\n", $ver[2], $ver[3]);
$this->ver = ['id' => $ver[2], 'date' => $ver[3]]; // remember the version
}
function emitTrans($trans) {
echo sprintf("Trans ver-id = %s serial = %s value = %s date = %s\n", $this->ver['id'], $trans[1], $trans[2], $trans[3], $trans[4]);
}
function outr($x) {
print_r($x);
echo "\n";
}
}
$p = new Parser;
$p->parse('#VER 1 5 20170128
{
#TRANS 8000 {} 4016.00 20170128 "something"
#TRANS 1100 {} -4016.00 20170128 "something"
}
#VER 1 6 20170128
{
#TRANS 8010 {} 5016.00 20170128 "something else"
#TRANS 1130 {} -5016.00 20170128 "something else"
}');
如果您想使用正则表达式,可以执行以下操作:
preg_match_all('/#VER (.*)\s*\{((\s*#TRANS\s*[0-9]+\s\{.*\}.*$)*\s*)\}/msU', $text, $matches);
$size = sizeof($matches[0]);
for($i = 0; $i < $size; $i++){
$text = $matches[2][$i];
echo "================\n";
echo $matches[1][$i]."\n";
preg_match_all('/\s*#TRANS\s([0-9]+)\s(\{.*\})\s([0-9\-\.]+)\s([0-9]+)\s"(.*)"$/', $text, $matches2);
$size2 = sizeof($matches2[0]);
for($j = 0; $j < $size2; $j++){
echo $matches2[1][$j]."\n";
echo $matches2[2][$j]."\n";
echo $matches2[3][$j]."\n";
echo $matches2[4][$j]."\n";
echo $matches2[5][$j]."\n";
}
}
如果愿意,可以拆分标题($matches[1][$i])
如果您想使用正则表达式,类似这样的操作可以:
preg_match_all('/#VER (.*)\s*\{((\s*#TRANS\s*[0-9]+\s\{.*\}.*$)*\s*)\}/msU', $text, $matches);
$size = sizeof($matches[0]);
for($i = 0; $i < $size; $i++){
$text = $matches[2][$i];
echo "================\n";
echo $matches[1][$i]."\n";
preg_match_all('/\s*#TRANS\s([0-9]+)\s(\{.*\})\s([0-9\-\.]+)\s([0-9]+)\s"(.*)"$/', $text, $matches2);
$size2 = sizeof($matches2[0]);
for($j = 0; $j < $size2; $j++){
echo $matches2[1][$j]."\n";
echo $matches2[2][$j]."\n";
echo $matches2[3][$j]."\n";
echo $matches2[4][$j]."\n";
echo $matches2[5][$j]."\n";
}
}
如果愿意,可以拆分标题($matches[1][$i])
DB架构到底是什么?请给我们展示一个你所期望的行的例子,不要试图把它全部塞进一个表达式中,从而使事情变得过于复杂,这将是我的建议。。。首先编写一个相当简单的表达式,将其分解为两个组件-\VER。。。{…}
,然后在上面循环并从那里获取…更新了帖子。当然,我不可能一次完成,分多个步骤运行也完全可以:)不确定如何将每行的行放在括号内,但是DB架构到底是什么?请给我们展示一个预期行的示例不要试图将其全部塞进一个表达式中,从而使事情变得过于复杂,我的建议是。。。首先编写一个相当简单的表达式,将其分解为两个组件-\VER。。。{…}
,然后在上面循环并从那里获取…更新了帖子。当然,我不可能一次完成,而且分多个步骤运行也完全可以:)但不知道如何将每行的行放在括号内