我使用preg_match_all()如下:
preg_match_all('/("user":"(.*?)".*?-->)/', $input_lines, $output_array);
在字符串上,我想让它得到注解块中“user”后面的任何内容(说来话长)。所以让我们假设$input_lines是这样的:
<!-- block {"user":"josh-hart", 1234566 ,"hide":false} /-->
<!-- block {"user":"jalen-brunson", 7744633 ,"hide":true} /-->
<!-- block {"user":"julius-randle", 333333,"hide":false} /-->
<!-- block {"user":"obi-toppin", 4hh3n33n33n, /-->
<!-- block {"user":"rj-barrett", nmremxxx!! ,"hide":true} /-->
<!-- block {"user":"mitch-robinson",yahaoao /-->
我想让它和用户匹配。但这里的事情,我只想用户,如果"hide":true
不出现在/-->
之前。所以对于这个字符串,我希望匹配的是:
josh-hart, julius-randle, obi-toppin, mitch-robinson
这在正则表达式中被称为什么,我该怎么做?
3条答案
按热度按时间ecr0jaav1#
假设打开和关闭一个注解是从
<!--
到-->
,并且在这之间没有其他的使用,你可以首先得到包含<!-- ... "hide":true ... -->
的匹配,而不需要穿过注解的打开或关闭。然后,您可以获得用户名的单个匹配,仍然在评论标记之间,并且独立于出现的顺序。
模式匹配:
<!--
文字匹配(?:(?!-->|"hide":).)*+
(可选)使用Tempered greedy token重复匹配任何后面没有直接跟-->
或"hide":
的字符"hide":true\b
匹配"hide":true
,后跟字边界,以防止部分字匹配(?:(?!-->).)*/-->
匹配直到关闭-->
(*SKIP)(*F)
跳过当前匹配|
或<!--
按字面匹配(?:(?!-->|"user").)*
可选重复匹配任何不直接跟有-->
或"user:
的字符"user":"\K
匹配"user":"
并忘记目前匹配的内容[^"]+
匹配1+除"
以外的字符(您要匹配的用户名)(?="(?:(?!-->).)*-->)
向右置位-->
注意,用户名的匹配可以更具体,目前匹配的是一个或多个字符,而不是双引号
[^"]+
,也可以是空格或换行符。如果只想匹配除双引号以外的非空格字符,则可以将其更改为[^\s"]+
。请参见regex demo。
clj7thdc2#
正如@bobblebubble所建议的,你可以使用
(*SKIP)(*FAIL)
组合来跳过你不想匹配的内容:试试on regex101.com。
e5nszbig3#
您可以尝试:
说明:
user":"([^"]+)"
-在匹配user":"
之后,它会查找"
内部的字符,直到找到"
。()
确保第一个捕获组。(?!.*"hide":true
负向前看,以确定在此之后没有"hide":true
。(?=.*\/-->)
正向前看,以确保/-->
之前没有"hide":true
Demo