preg_match_all 为每个匹配循环,验证是不是为空以设置空值以插入表 mysql
Posted
技术标签:
【中文标题】preg_match_all 为每个匹配循环,验证是不是为空以设置空值以插入表 mysql【英文标题】:preg_match_all loop for each match, verify if empty to set null values to insert in table mysqlpreg_match_all 为每个匹配循环,验证是否为空以设置空值以插入表 mysql 【发布时间】:2022-01-01 12:16:10 【问题描述】:我有 10 行要从文件文本中提取其他行,有些是空的但存在,有些不存在但无论如何我必须插入它们,使用正则表达式可以将文本分成 10 组,我使用 preg_match_all 匹配组并生成一个匹配的数组,但如果行不存在不匹配,我希望插入值组插入到 mysql 表中,如果值为空,则设置为 NULL。
我只需要它们的值,但首先验证键是否存在并为此添加缺失的键和 NULL 值。
如果值为空,则设置NULL,如果该组在文本文件中不存在,则添加一个值以设置NULL以插入到表mysql中。
请参阅更新问题
我应该使用 array_push、array_key_exists 还是在正则表达式中为每个组分配一个名称?
最后,如何循环每个匹配项?使用 preg_match_all 只生成一个完全匹配的数组,但我的表 mysql 只有 10 列,每个组正则表达式一列。
更新问题:我改写了帖子 11/24/21 01.00
例如完整的数据是 10 行
/*
First Name :NameAAAAAA
LINE TO EXCLUDE : this line is to exclude
Last Name :LastAAAAAA
LINE TO EXCLUDE : this line is to exclude
Gender = (F/M) :
ANOTHER LINE TO EXCLUDE : this line is to exclude
TEST INFO 1 :TI1AAAAAA
ANOTHER LINE TO EXCLUDE : this line is to exclude
TEST INFO 2 :
TEST INFO 3 :TI3AAAAAA
First Name :NameBBBBBB
LINE TO EXCLUDE : this line is to exclude
Last Name :LastBBBBBB
LINE TO EXCLUDE : this line is to exclude
Gender = (F/M) :
First Name :NameCCCCCC
LINE TO EXCLUDE : this line is to exclude
Last Name :LastCCCCCC
LINE TO EXCLUDE : this line is to exclude
Gender = (F/M) :M
ANOTHER LINE TO EXCLUDE : this line is to exclude
TEST INFO 1 :
ANOTHER LINE TO EXCLUDE : this line is to exclude
TEST INFO 2 :TI2CCCCCC
TEST INFO 3 :
*/
使用正则表达式仅提取行(6行):
https://regex101.com/r/hWzvOr/1
/.*(?:First Name).*|.*(?:Last Name).*|.*(?:Gender = \(F\/M\)).*|.*(?:TEST INFO 1).*|.*(?:TEST INFO 2).*|.*(?:TEST INFO 3).*/g
使用正则表达式模式提取后的以下字符串:有可能发现不存在的行(参见 NameBBBBBB 组中的 TEST INFO 1-2-3)
$str = '
First Name :NameAAAAAA
Last Name :LastAAAAAA
Gender = (F/M) :
TEST INFO 1 :TI1AAAAAA
TEST INFO 2 :
TEST INFO 3 :TI3AAAAAA
First Name :NameBBBBBB
Last Name :LastBBBBBB
Gender = (F/M) :
First Name :NameCCCCCC
Last Name :LastCCCCCC
Gender = (F/M) :M
TEST INFO 1 :
TEST INFO 2 :TI2CCCCCC
TEST INFO 3 :
';
如果不存在(不匹配)通过动态创建键并将值设置为NULL,如果值为空设置为NULL。
必须生成,(请参阅组 NameBBBBBB 中的 TEST INFO 1-2-3)
Array
(
[0] => Array
(
[0] => First Name :NameAAAAAA
[1] => Last Name :LastAAAAAA
[2] => Gender = (F/M) :
[3] => TEST INFO 1 :TI1AAAAAA
[4] => TEST INFO 2 :
[5] => TEST INFO 3 :TI3AAAAAA
[6] => First Name :NameBBBBBB
[7] => Last Name :LastBBBBBB
[8] => Gender = (F/M) :
[9] => TEST INFO 1 :
[10] => TEST INFO 2 :
[11] => TEST INFO 3 :
[12] => First Name :NameCCCCCC
[13] => Last Name :LastCCCCCC
[14] => Gender = (F/M) : M
[15] => TEST INFO 1 :
[16] => TEST INFO 2 :TI2CCCCCC
[17] => TEST INFO 3 :
)
)
如果在正则表达式中不匹配,如何创建密钥?循环生成一个包含所有数据的数组,但我将每个循环的 6 行值插入到一个 6 列的表中到 mysql 中?
提前致谢。
问候。
意大利。
【问题讨论】:
我玩过它和came up with this (demo)。也许有用。 感谢您的回答,我改写了帖子,数据只有从匹配正则表达式的行中提取的相同行,而不是所有数据。请在帖子中查看我的更新问题。再次感谢。 【参考方案1】:我将分多个步骤处理:
$str = '
APPLICATION ID :AAAAA#AA#0101
STATUS P=PENDING/A=ACTIVE :A
VALID-TO DATE :711231
APPLICATION TYPE (A/G) :A
DESCRIPTIVE TEXT :DESC folder AAAAA
OWNER ID :
RANDOM INFO :
PERIOD OR RUN CYCLE GROUP NAME :QAZ123XX
RUN CYCLE VALID-FROM :711230
RUN CYCLE VALID-TO :711231
RUN CYCLE DESCRIPTION :MANUAL ORDER
RUN RANDOM IFO :
APPLICATION ID :BBBBB#BB#0101
STATUS P=PENDING/A=ACTIVE :A
VALID-TO DATE :711231
APPLICATION TYPE (A/G) :A
DESCRIPTIVE TEXT :
OWNER ID :OWNER1
RANDOM INFO :
';
加
$groups = explode('APPLICATION ID', $str);
foreach ($groups as $group)
echo "----\n";
$hash = [];
if (empty($group)) continue;
$group = 'APPLICATION ID' . $group;
$lines = preg_split("/\n/", $group);
foreach($lines as $line)
$kv = explode(':', $line);
if (count($kv) == 2 && trim($kv[1]) != '')
$hash[trim($kv[0])] = trim($kv[1]);
print_r($hash);
// TODO: Build an INSERT with just the values in $hash
// Meanwhile, each column should be `DEFAULT NULL`.
产量:
----
Array
(
)
----
Array
(
[APPLICATION ID] => AAAAA#AA#0101
[STATUS P=PENDING/A=ACTIVE] => A
[VALID-TO DATE] => 711231
[APPLICATION TYPE (A/G)] => A
[DESCRIPTIVE TEXT] => DESC folder AAAAA
[PERIOD OR RUN CYCLE GROUP NAME] => QAZ123XX
[RUN CYCLE VALID-FROM] => 711230
[RUN CYCLE VALID-TO] => 711231
[RUN CYCLE DESCRIPTION] => MANUAL ORDER
)
----
Array
(
[APPLICATION ID] => BBBBB#BB#0101
[STATUS P=PENDING/A=ACTIVE] => A
[VALID-TO DATE] => 711231
[APPLICATION TYPE (A/G)] => A
[OWNER ID] => OWNER1
)
另一个提示:NULLIF(?, '')
【讨论】:
感谢您的回答,在 Yields 部分中,在第一个数组中缺少键 OWNER ID :具有空值,在第二个数组中应该有数组键并且值是空的(不存在)[描述性文本] [PERIOD OR RUN CYCLE GROUP NAME] => [RUN CYCLE VALID-FROM] => [RUN CYCLE VALID-TO] => [RUN CYCLE DESCRIPTION] =>,我在您的回答中读到,这样做会丢失。请在帖子中查看我的更新问题。再次感谢。【参考方案2】:-
构建一个数组,将所有需要的键和值设置为 null:
$columns = [
'APPLICATION ID',
'STATUS P=PENDING/A=ACTIVE',
/*...*/
'RUN CYCLE DESCRIPTION'
];
$keys = array_fill_keys($columns, null);
-
构建一个模式来提取字符串中存在的键和值。为此,将所有需要的键放入模式中是完全没用的,您只需要使用捕获组(在此处命名)将键与每个匹配的值隔离开(注意 value 组是可选):
$pat = '~^ \h*+ (?<key> [^:\n]* [^:\s] ) \h* : (?<value> \S+ (?:\h+\S+)* )? ~xm';
-
将
preg_match_all
与PREG_UNMATCHED_AS_NULL
标志一起使用:当可选值 组不匹配时,返回值为null
而不是空字符串。
使用preg_match_all
匹配结果,使用$matches['key']
和$matches['value']
子数组构建一个关联数组(请注意,这个数组与数组$keys
具有相同的键,但最终缺少一些键)。
那么你所要做的就是将$keys
数组与这个新数组合并,得到一个包含你感兴趣的键/值对的关联数组。
if ( preg_match_all($pat, $yourstring, $matches, PREG_UNMATCHED_AS_NULL) )
$result = array_combine($matches['key'], $matches['value']);
// $result = array_intersect_key($result, $keys); // if you need to exclude some key/value pairs from the string
$result = array_merge($keys, $result);
1,2,3 Aquafresh® 3
【讨论】:
感谢您的回答,我改写了帖子,数据只有从匹配正则表达式的行中提取的相同行,而不是所有数据。在您的步骤 3) 中,$result 数组中只有一个最后一个循环,如果这些行不存在,则该信息将与前一个循环中的数据合并。请在帖子中查看我的更新问题。再次感谢。 @italo_pm:如果您有要排除的行,这不是问题,请在array_merge
行之前添加$result = array_intersect_key($result, $keys);
。
@italo_pm:在应用脚本之前拆分您的字符串,并立即处理一个块。
感谢 Casimir 的回答,使用 array_intersect_key 排除行工作正常,但最后一个数组 $result 只有最后一个结果循环而不是所有行循环,如何保存所有行循环? ` $result = array_combine($matches['key'], $matches['value']); $result = array_intersect_key($result, $keys); $result = array_merge($keys, $result); print_r( $result, true ) Array ( [First Name] => NameCCCCCC [Last Name] => LastCCCCCC [Gender = (F/M)] => M [TEST INFO 1] => [TEST INFO 2] => TI2CCCCCC [测试信息 3] => )` 再次感谢。
@italo_pm:存储每个块的结果:3v4l.org/5GvSS(或在循环中一次将它们发送到数据库)。以上是关于preg_match_all 为每个匹配循环,验证是不是为空以设置空值以插入表 mysql的主要内容,如果未能解决你的问题,请参考以下文章
突出显示 preg_match_all() 的主题字符串中的匹配结果
PHP 正则表达式匹配 preg_match 与 preg_match_all 函数