【问题标题】:Regex lookahead non capturing with if/then使用 if/then 进行正则表达式前瞻非捕获
【发布时间】:2017-05-07 03:43:32
【问题描述】:

我有一些损坏的 JSON 文件想要修复。 问题是 AcquisitionDateTime 字段之一格式不正确:

{
    "AcquisitionDateTime": 2016-04-28T17:09:39.515625,
}

我想要做的是将值包含在括号中。我可以使用正则表达式轻松做到这一点:

perl -pi -e 's/\"AcqDateTime\": (.*),/\"AcqDateTime\": \"\1\",/g' t.json

现在,我想扩展正则表达式,以便在 JSON 未损坏的情况下,内容不会被两次包裹在“”中。我面临的问题是我不知道如何混合前瞻、if/then 语句和捕获组。这是我的尝试:

Lookahead, if you find a ", then capture what is between it. Else capture everything.
perl -pi -e 's/\"AcqDateTime\": (?(?=\")\"(.*)\"|(.*)),/\"AcqDateTime:\" \"\1\",/g' t.json

这是我有兴趣更正的部分:

Lookahead for a \"  -> if yes, then capture without it. \"(.*)\" Else capture all (.*)
(?(?=\")\"(.*)\"|(.*)),

有人可以向我解释我做错了什么吗?

提前致谢。

【问题讨论】:

  • 提示:\1 应该是 $1。并且无需逃避所有那些"

标签: json regex perl


【解决方案1】:

匹配时间戳的良好开端是

\S+

但这也匹配逗号,所以我们切换到

 [^\s,]+

现在,您也想避免匹配引号。

 [^\s",]+

这就是你所需要的。

perl -i -pe's/"AcqDateTime":\s*+\K([^\s",]+)/"$1"/g' t.json

【讨论】:

  • 为什么不只使用[^"]+
  • @Master DJon,我的回答已经逐步解释了我是如何获得我使用的东西的。您的建议将与逗号匹配,因此它绝对行不通。您可以删除\s,尽管理论上逗号前可能有空格,不应包含在双引号中。
【解决方案2】:

以下正则表达式包括对引号的部分换行(即仅在值的开头或结尾)、两端缺少换行或空值的检查:

perl -pi -e 's/\"AcqDateTime\": (|(?<!\")[^\"].*|.*[^\"](?!\")),/\"AcqDateTime\": \"\1\",/g' t.json

其中(|(?&lt;!\")[^\"].*|.*[^\"](?!\")) 包括:

  • 空字符串值,如{ "AcquisitionDateTime": }
  • (?&lt;!\")[^\"].*:不以引号开头的值,如{ "AcquisitionDateTime": 2016" },或
  • .*[^\"](?!\"):不以引号结尾的值,如{ "AcquisitionDateTime": "2016 }

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    相关资源
    最近更新 更多