提取由 space 分隔的组
Extract groups separated by space
我有以下字符串(示例):
Loader[data-prop data-attr="value"]
可以有 1 - n 个属性。我想提取每个属性。 (数据属性,数据属性="value")。我尝试了很多不同的方式,例如 \[(?:(\S+)\s)*\]
但我没有做对。表达式应该写成PREG风格..
怎么样 [\s\[]([^\s\]]+(="[^"]+)*)+
给予
第 1 场比赛:data-prop
第 2 场比赛:data-attr="value"
我建议使用正则表达式获取所有键值对:
'~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?)?)~'
(参见 regex demo)然后
$re = '~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?)?)~';
$str = "Loader[data-prop data-attr=\"value\" more-here='data' and-one-more=\"\"]";
preg_match_all($re, $str, $matches);
$arr = array();
for ($i = 0; $i < count($matches); $i++) {
if ($i != 0) {
$arr = array_merge(array_filter($matches[$i]),$arr);
}
}
print_r(preg_grep('~\A(?![\'"]\z)~', $arr));
输出:
Array
(
[3] => data-prop
[4] => data-attr="value"
[5] => more-here='data'
[6] => and-one-more=""
[7] => Loader
)
关于正则表达式的注释(它看起来太复杂了):
(?:([^][]*)\b\[|(?!^)\G)
- 一个边界:我们只从 [
开始匹配,这个 [
前面有一个单词 (a-zA-Z0-9_
) 字符(有 \b\[
),或者右边成功匹配后((?!^)\G
)。 此外,([^][]*)
会将 [
之前的部分捕获到组 1 中。
\s*
- 匹配零个或多个空白符号
(\w+(?:-\w+)*)
- 捕获到第 2 组 "words",如 "word1" 或 "word1-word2"..."word1-wordn"
(?:=(["\'])?[^\]]*?)?
- 可选组(由于 (?:...)?
)匹配
=
- 等号
(["\'])?
- 第 3 组(检查值定界符的辅助组)捕获 "
、'
或什么都不捕获
[^\]]*?
- (值)零个或多个 ]
以外的字符尽可能少
</code> - 结束 <code>'
或 "
(在第 3 组中捕获的相同值)。
由于我们无法摆脱捕获 '
或 "
,我们可以 preg_grep
我们不感兴趣的所有元素 preg_grep('~\A(?![\'"]\z)~', $arr)
where \A(?![\'"]\z)
匹配任何不等于 '
或 "
.
的字符串
我有以下字符串(示例):
Loader[data-prop data-attr="value"]
可以有 1 - n 个属性。我想提取每个属性。 (数据属性,数据属性="value")。我尝试了很多不同的方式,例如 \[(?:(\S+)\s)*\]
但我没有做对。表达式应该写成PREG风格..
怎么样 [\s\[]([^\s\]]+(="[^"]+)*)+
给予
第 1 场比赛:data-prop
第 2 场比赛:data-attr="value"
我建议使用正则表达式获取所有键值对:
'~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?)?)~'
(参见 regex demo)然后
$re = '~(?:([^][]*)\b\[|(?!^)\G)\s*(\w+(?:-\w+)*(?:=(["\'])?[^\]]*?)?)~';
$str = "Loader[data-prop data-attr=\"value\" more-here='data' and-one-more=\"\"]";
preg_match_all($re, $str, $matches);
$arr = array();
for ($i = 0; $i < count($matches); $i++) {
if ($i != 0) {
$arr = array_merge(array_filter($matches[$i]),$arr);
}
}
print_r(preg_grep('~\A(?![\'"]\z)~', $arr));
输出:
Array
(
[3] => data-prop
[4] => data-attr="value"
[5] => more-here='data'
[6] => and-one-more=""
[7] => Loader
)
关于正则表达式的注释(它看起来太复杂了):
(?:([^][]*)\b\[|(?!^)\G)
- 一个边界:我们只从[
开始匹配,这个[
前面有一个单词 (a-zA-Z0-9_
) 字符(有\b\[
),或者右边成功匹配后((?!^)\G
)。 此外,([^][]*)
会将[
之前的部分捕获到组 1 中。\s*
- 匹配零个或多个空白符号(\w+(?:-\w+)*)
- 捕获到第 2 组 "words",如 "word1" 或 "word1-word2"..."word1-wordn"(?:=(["\'])?[^\]]*?)?
- 可选组(由于(?:...)?
)匹配=
- 等号(["\'])?
- 第 3 组(检查值定界符的辅助组)捕获"
、'
或什么都不捕获[^\]]*?
- (值)零个或多个]
以外的字符尽可能少</code> - 结束 <code>'
或"
(在第 3 组中捕获的相同值)。
由于我们无法摆脱捕获 '
或 "
,我们可以 preg_grep
我们不感兴趣的所有元素 preg_grep('~\A(?![\'"]\z)~', $arr)
where \A(?![\'"]\z)
匹配任何不等于 '
或 "
.