【问题标题】:Regex - match 0 or 1 times正则表达式 - 匹配 0 或 1 次
【发布时间】:2015-11-14 09:29:46
【问题描述】:

我有以下正则表达式:

var re = /^(post|merge|delete) (\/WcfDataService1\.svc\/)(.*) HTTP\/1.1$[\s\S]*?(^{.+\}$)/im

这用于匹配批处理请求中的各种项目:

--batchitems
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /WcfDataService1.svc/Orders(123) HTTP/1.1

{"OrderID":"x58"}
  • 第一组:类型(POST/MERGE/DELETE)
  • 第二组:/WcfDataService1.svc/
  • 第三组:出现在 WcfDataService1.svc 之后的任何内容,在本例中:Orders(123)
  • 第四组:JSON 字符串

这很好用!当我执行re.match(str);时,返回一个数组如下:

[
    'POST',
    '/WcfDataService1.svc/',
    'Orders(123)',
    '{"OrderID":"x58"}'
]

但是,我希望 JSON 字符串在我的正则表达式中是可选的,因为它并不总是存在;例如:

--batchitems
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE /WcfDataService1.svc/Orders(123) HTTP/1.1

// EOL here

但是我的正则表达式在这里失败了,因为它试图匹配花括号并且找不到它们,所以整个正则表达式都失败了。

如何使(^{.+\}$) 成为可选(出现0 或1 次)?我试过(^{.+\}$){0,1},但还是不行。

有什么想法吗?

请参阅:https://regex101.com/r/pT3fG0/2https://regex101.com/r/nO8xZ7/1

【问题讨论】:

  • 可能有点愚蠢的建议,但您可以通过一些简单的字符串匹配来进行基本拆分,例如var lines = input.split("\n"),然后将正则表达式应用于每一行并计算行数等。跨度>
  • 你试过(^{.+\}$)?吗?或者可能是(^{.+\}$){?}...我不是正则表达式专家。

标签: javascript json regex


【解决方案1】:

编辑 1

使用 ? 将 json 部分设为可选,如下所示:

^(post|merge|delete) (\/WcfDataService1\.svc\/)(.*) HTTP\/1.1$(?:[\s]*?(^{.+\}$))?

DEMO

【讨论】:

  • 嗯,当我这样做时,它无法匹配 JSON 字符串:regex101.com/r/nO8xZ7/2
  • @PruthviRaj 您将引擎从 JS 更改为 PCRE?我不确定这是一个合适的解决方案吗?
  • 太棒了-谢谢!你能解释一下添加的作用吗?那是使用负前瞻吗?
  • @keldar 不,它不是负面的后视,在 (?:[\s]*?(^{.+\}$))? 中,(?:..) 是一个非捕获组,它不捕获文本,然后在最后生成 ?这都是可选的
【解决方案2】:

另一种选择可能是:

(^(post|merge|delete)\s(\/WcfDataService1\.svc\/)(.*)(HTTP\/1\.1)([\s]*)($|^{.*}))

这如您所愿。可以看here

【讨论】:

  • 谢谢!这是一个相当干净的实现。
  • 别担心,我尽量让它靠近你的,这样更容易理解。
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多