【问题标题】:Regex: Find tagged strings in text正则表达式:在文本中查找标记的字符串
【发布时间】:2020-01-21 16:04:53
【问题描述】:

我得到以下查询字符串,其中始终在字符串末尾包含几个标记值(key: value 对):

Lorem ipsum age:85 date:15.05.2015 sender: user: John Doe

“Lorem ipsum”是一个应该被忽略的字符串,因为它不是一对。 以下对有效:

  • age85
  • date15.05.2015
  • userJohn Doe

如果在冒号后找不到任何内容,则应忽略标签。 它们的内容还可以包含直到下一个标签键的空格。

这是我目前得到的:

/([\w-]+):\s*(.+?)(?!\s+[\w-]+:)?/g

但由于某种原因,它似乎只匹配值的第一个字符,并且还切入了“用户”标签(regexr playground):

age:8
date:1
sender: u
ser:J

任何帮助将不胜感激!

【问题讨论】:

    标签: regex regex-lookarounds


    【解决方案1】:

    你可以使用

    (\w[\w-]*):(?!\s+\w[\w-]*:|\s*$)\s*(.*?)(?=\s+\w[\w-]*:|$)
    

    regex demo

    详情

    • (\w[\w-]*) - 捕获组 1:一个单词 char 后跟 0+ 单词或连字符 chars
    • : - 冒号
    • (?!\s+\w[\w-]*:|\s*$) - 如果在当前位置的右侧有 1+ 个空格,一个单词 char 后跟 0+ 个单词或连字符,然后 : 或 0+ 个空格,则否定前瞻失败匹配字符串的
    • \s* - 0+ 个空格
    • (.*?) - 第 2 组:除换行符之外的任何零个或多个字符,尽可能少,直到最近的...
    • (?=\s+\w[\w-]*:|$) - 1+ 个空格,一个单词 char 后跟 0+ 个单词或连字符,然后是 : 或只是字符串的结尾。

    【讨论】:

    • See your updated demo 以更好地理解失败的原因。请注意,您的正则表达式模式会选择普通文本。事实上,单独的正则表达式无法“知道”多字值的开始和结束位置,这就是为什么在 JSON 中此类值必须用双引号引起来。
    • 在这种情况下,“John Doe ipsum”仍将被假定为“正确”,因为所有标签都放在字符串的末尾。如果不是,那么它是最后一个标签值的一部分,只是一个用户错误。 (用引号将它们括起来可能是更明智的选择,但在这种情况下已决定反对......)
    【解决方案2】:

    我似乎从以下模式中获得了不错的成绩:

    (?<!\S)\S+:\s*\S*[^:\s](?!\S)
    

    Demo

    这里的策略是匹配一个后跟冒号的键,然后是可选的空格和一个 not 的术语也以冒号结尾(以防止溢出到另一个键)。这是正则表达式的解释:

    (?<!\S)   assert that what precedes the start of the key is either whitespace
              or the start of the string
    \S+       match one or more non whitespace characters (the key)
    :         followed by :
    \s*       followed by optional whitespace
    \S*       a value, zero or more non whitespace characters
    [^:\s]    ending in a non colon
    (?!\S)    assert that what follows is either whitespace or the end of the string
    

    【讨论】:

    • 你得到userJohn,但John Doe 是预期的。
    • 负面的lookbehind使其不那么有用,它也不像其他答案那样匹配“Doe”,~~不是说它是要求,~~我喜欢这两个答案。
    • @Fixation 匹配John Doe的要求。
    • @WiktorStribiżew 那么 OP 的数据就是问题所在。我们无法真正知道Doe 是密钥的一部分。如果你仔细看,你会看到领先的内容Lorem ipsum
    • 那是一个key,OP有一个[\w-]+模式来识别它,value可以包含任何char。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    相关资源
    最近更新 更多