regex 我想要一个正则表达式模式来抓取模式中的文本,该模式排除了后跟特定字符串的匹配项

7cjasjjr  于 2023-06-25  发布在  其他
关注(0)|答案(3)|浏览(96)

我使用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

这在正则表达式中被称为什么,我该怎么做?

ecr0jaav

ecr0jaav1#

假设打开和关闭一个注解是从<!---->,并且在这之间没有其他的使用,你可以首先得到包含<!-- ... "hide":true ... -->的匹配,而不需要穿过注解的打开或关闭。
然后,您可以获得用户名的单个匹配,仍然在评论标记之间,并且独立于出现的顺序。

<!--(?:(?!-->|"hide":).)*+"hide":true\b(?:(?!-->).)*/-->(*SKIP)(*F)|<!--(?:(?!-->|"user":).)*"user":"\K[^"]+(?="(?:(?!-->).)*-->)

模式匹配:

  • <!--文字匹配
  • (?:(?!-->|"hide":).)*+(可选)使用Tempered greedy token重复匹配任何后面没有直接跟-->"hide":的字符
  • "hide":true\b匹配"hide":true,后跟字边界,以防止部分字匹配
  • (?:(?!-->).)*/-->匹配直到关闭-->
  • (*SKIP)(*F)跳过当前匹配
  • |
  • <!--按字面匹配
  • (?:(?!-->|"user").)*可选重复匹配任何不直接跟有-->"user:的字符
  • "user":"\K匹配"user":"并忘记目前匹配的内容
  • [^"]+匹配1+除"以外的字符(您要匹配的用户名)
  • (?="(?:(?!-->).)*-->)向右置位-->
    注意,用户名的匹配可以更具体,目前匹配的是一个或多个字符,而不是双引号[^"]+,也可以是空格或换行符。如果只想匹配除双引号以外的非空格字符,则可以将其更改为[^\s"]+

请参见regex demo

clj7thdc

clj7thdc2#

正如@bobblebubble所建议的,你可以使用(*SKIP)(*FAIL)组合来跳过你不想匹配的内容:

^                     # Match at the start of a line
.*                    # anything
"hide"\s*:\s*true     # followed by '"hide":true'
.*                    # then anything until the end of the line
                      # (i.e. a line that contains '"hide":true')
(*SKIP)(*FAIL)        # which we tell the engine to skip entirely
|                     # or
"user"\s*:\s*"\K      # '"user":"', which we forfeit,
[^"]+                 # followed by 1 or more non-quote characters.

试试on regex101.com

e5nszbig

e5nszbig3#

您可以尝试:

user":"([^"]+)"(?!.*"hide":true(?=.*\/-->))

说明:

  • user":"([^"]+)"-在匹配user":"之后,它会查找"内部的字符,直到找到"
  • ()确保第一个捕获组。
  • (?!.*"hide":true负向前看,以确定在此之后没有"hide":true
  • (?=.*\/-->)正向前看,以确保/-->之前没有"hide":true

Demo

相关问题