正则表达式在使用时不匹配?如果不存在第一个字符

时间:2018-07-12 22:14:33

标签: c# regex

这是我的C#正则表达式:

\"([a-zA-Z0-9]*)\":\"?([a-zA-Z0-9]*)\"?,?}?

我正在使用示例字符串

测试here
{"RestrictedCompany": "","SQLServerIndex": 0,"SurveyAdmin": false}`

这是我认为正则表达式的作用:

  

部分1:寻找"一切":的模式   并存储任何内容(不带引号)。

     

部分2:然后寻找:并存储所有内容,直到到达",}的停止字符

它很好地提取了第1部分,但是当"不存在时(即当第2部分没有字符串时)根本不提取第2部分。所以我有两个问题:

  • 为什么我当前的代码没有整理第2部分? (以及如何解决)
  • 有没有一种方法可以使任何事物的匹配更加灵活? (我尝试使用\S,但是太贪心了)

1 个答案:

答案 0 :(得分:4)

首先,不要编写自己的JSON解析器。使用专业人士写的一本。您在这里重新发明了一个相当复杂的轮子。

也就是说,您还可以在这里学习有关如何编写,理解和调试正则表达式的课程,所以让我们来看一下。

  

为什么我当前的代码没有整理第2部分? (以及如何解决)

像正则表达式引擎一样学习推理。

我们来看一个简单的例子。我们将使用表达式

\"([a-zA-Z0-9]*)\":\"?([a-zA-Z0-9]*)\"?,?}?

我们将搜索以下字符串:

{"A": "B"}

用于正则表达式的实例。

好。

  • {与任何内容都不匹配,因此请跳过它。
  • "个匹配\",所以也许我们有一个匹配项。
  • A([a-zA-Z0-9]*)匹配,因此,也许我们也有一个匹配项。
  • 第二个"与第二个\"相匹配,所以我们还是不错的。
  • ::相匹配...
  • 我们现在正在尝试匹配\"?,零或一引号。我们有,一个空格。我们匹配零引号。
  • 我们现在正在尝试匹配([a-zA-Z0-9]*)(任意数量的字母数字)。我们有,一个空格。因此,我们的字母数字为零。
  • 我们现在正尝试再次匹配\"?,并且我们再次拥有,因此我们匹配零。
  • 我们现在正在尝试匹配,?,其中有零个。
  • 我们现在正在尝试匹配}?,我们又将其设为零
  • 我们完成了。我们已经成功匹配了模式,匹配为"A":
  • 现在继续前进;我们可以匹配字符串其余部分中的任何内容吗?否。模式需要一个:,并且在字符串的其余部分中没有:,所以我不会花力气。显然比赛将会失败。

如果这不是您要匹配的模式,请编写其他模式。例如,如果希望在冒号前后有任意空格,则可能在冒号前后需要/s*。另外,如果您在:之后要求一个值,那么为什么要在冒号 之后加上所有内容呢? “必需”和“可选”是相反的。


那么在这里做什么是正确的呢?再次,正确的做法是停止尝试使用正则表达式解决此问题,并像明智的人一样使用json解析器。但是假设我们确实想用正则表达式对此进行解析。我们该怎么做?

我们通过将问题分解为更小的部分来实现。

我们真正想要匹配什么?让我们命名每个要匹配的事物,然后写一个冒号,然后说出事物的结构是什么:

DESIRED : NAME OPTIONAL_WHITESPACE COLON OPTIONAL_WHITESPACE VALUE

好,将其分解。什么名字?

NAME : QUOTE NAMECONTENTS QUOTE

继续分解它。

NAMECONTENTS : any alphanumeric text of any length

问自己是真的吗? ""NAME吗? "1234"NAME吗? "$"NAME吗?调整模式,直到正确为止。我们现在就讨论这个。

现在这很困难:

VALUE : BOOLEAN_LITERAL
VALUE : NUMBER_LITERAL
VALUE : STRING_LITERAL

这可以是三件事之一。再说一遍,继续分解:

BOOLEAN_LITERAL : true
BOOLEAN_LITERAL : false

继续前进;您可以从此处了解如何操作。

现在为每个部分制作一个正则表达式,然后将其放回原处

  • NAMECONTENTS的正则表达式为\w*
  • QUOTE的正则表达式为\"
  • 因此,NAME的正则表达式为\"\w*\"
  • 我们要捕获名称文本,因此将其放在一个组中:\"(\w*)\"

太好了。同样:

  • OPTIONAL_WHITESPACE的正则表达式为\s*
  • COLON的正则表达式为:
  • 因此我们的正则表达式以\"(\w*)\"\s:\s开头

现在我们需要处理VALUE。但是我们已经分解了。 BOOLEAN_LITERAL的正则表达式是什么?那是[true|false]

继续前进;为其他文字创建正则表达式,然后从叶到根构建您的正则表达式