【发布时间】:2021-09-14 17:06:58
【问题描述】:
我正在尝试解析一个查询,我需要对其进行修改以将特定属性及其值替换为另一个属性和不同的值。我正在努力编写一个匹配我需要的指定属性及其值的正则表达式。
这里有一些例子来说明我的观点。 test:property 是我们需要匹配的属性名。
- 具有单个值的属性:
test:property:schema:Person - 具有多个值的属性(可以有多少个值没有限制 - 本示例使用 3 个):
test:property:(schema:Person OR schema:Organization OR schema:Place) - 括号中包含单个值的属性:
test:property:(schema:Person) - 查询字符串中具有另一个属性的属性(即字符串的其他部分我不感兴趣):
test:property:schema:Person test:otherProperty:anotherValue
另请注意,其他组合也是可能的,例如其他属性位于我需要捕获的属性之前,我的属性具有多个值,而查询中存在另一个属性。
我想在整个test:property 部分上匹配在该匹配中捕获的每个值。鉴于上面的例子,这些是我正在寻找的结果:
| # | Match | Groups |
|---|---|---|
| 1 | test:property:schema:Person |
schema:Person |
| 2 | test:property:(schema:Person OR schema:Organization OR schema:Place) |
schema:Personschema:Organizationschema:Person
|
| 3 | test:property:(schema:Person) |
schema:Person |
| 4 | test:property:schema:Person |
schema:Person |
注意:#1 和#4 产生相同的输出。我想说明应该忽略字符串的其余部分(我只需要更改test:property 键和值)。
schema:Person 的模式定义为\w+\:\w+,即一个或多个单词字符,后跟一个冒号,然后是一个或多个单词字符。
如果我们用名称定义字符串的已知部分,我想我可以表达我想要匹配的内容。
-
schema:Person-<TypeName>- 请注意,在这种情况下,第一部分schema不是固定的,可以不同 -
test:property-<MatchProperty>
<MatchProperty>: // property name (which is known and the same - in the examples this is `test:property`) followed by a colon
( // optional open bracket
<TypeName>
(OR <TypeName>)* // optional additional TypeNames separated by an OR
) // optional close bracket
我发现的每个示例在重复部分都有简单的字母数字字符,但我的重复模式包含冒号,这似乎让我感到困惑。我得到的最接近的是:
(test\:property:(?:\(([\w+\:\w+]+ [OR [\w+\:\w+]+)\))|[\w+\:\w+]+)
当没有其他属性时,这可以正常工作(尽管例如 #2 的匹配包含整个属性和值作为第一组结果,第二组包含属性值)但是当包含其他属性时会变得疯狂。
另外,将正则表达式放入https://regex101.com/ 我知道这是不正确的,因为方括号中的反斜杠字符完全匹配。我开始尝试使用捕获组和非捕获组,但在放弃之前做到了这一点!
(?:(\w+\:\w+))(?:(\sOR\s))*(?:(\w+\:\w+))*
【问题讨论】:
-
最多有 3 个“组”吗?
-
所以您的
<MatchProperty>并不总是test:property?你<TypeName>的第一部分并不总是schema?你能添加一个特定的语言吗?例如,.NET 可以捕获的不仅仅是捕获组中的最后一个事件。 -
测试用例 #1 和 #4 相同!?
-
组数在模式内设置。我建议在
test:property之后捕获整个部分,然后用空格+OR+ 空格分割捕获的值。见\btest:property:(\()?(\w+:\w+(?:\s+OR\s+\w+:\w+)*)(?(1)\))regex demo -
我已更新问题以回答这些 cmets 中提出的所有问题,我希望这能增加一些清晰度。简而言之:有无限数量的组,
<MatchProperty>是一个已知值,<TypeName>的第一部分并不总是schema,我已经阐明了示例 #1 和 #4 的原因