我正在寻找符合以下情况的正则表达式(在C#中):
等
{A} {B}
等
一个{B}
其中a,b,c可以是任何字符串。
到目前为止,我有类似的内容:。* [\ {]。+?[\}]。* 但这符合案例 {a} {b} 完全,而不是返回两个匹配,即 {a} 和 {b}
该表达式用于验证某些字符串是否为编码字符串。如果是,它需要从编码字符串中获取单独的部分(Regex.Matches()会很方便)并解析它们。
答案 0 :(得分:1)
你可以通过在正则表达式
周围组合一些递归逻辑来实现这一点此正则表达式将匹配嵌套三层深度的开括号和近似括号,如{a{b{c}}}{{{d}e}f}
\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}
虚线区域是基本搜索,其中搜索嵌套在自身内部,以满足您的需要。
在下面的示例中,我只是针对大多数示例运行正则表达式。将此正则表达式与foreach循环组合,该循环将获取每个Group 1并从当前字符串^[^{]*
的开头捕获所有非开放括号,然后通过上面的正则表达式递归地返回其余字符串以捕获内部值下一组括号,然后从字符串[^}]*$
的末尾捕获所有非近括号。
{a}
{a:b}
{a:{b}}
{a:{b:c}}
{a}{b}
{a}{b}{c}
{a{b{c}}}{{{d}e}f}
此C#.Net示例仅显示正则表达式的工作原理。了解第1组如何从最外面的括号组中获取内部文本。每个外部括号内的文本都被分成了它自己的数组位置,并且相应的外部括号被删除了。
using System;
using System.Text.RegularExpressions;
namespace myapp
{
class Class1
{
static void Main(string[] args)
{
String sourcestring = "sample text above";
Regex re = new Regex(@"\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}",RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
MatchCollection mc = re.Matches(sourcestring);
int mIdx=0;
foreach (Match m in mc)
{
for (int gIdx = 0; gIdx < m.Groups.Count; gIdx++)
{
Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames()[gIdx], m.Groups[gIdx].Value);
}
mIdx++;
}
}
}
}
$matches Array:
(
[0] => Array
(
[0] => {a}
[1] => {a:b}
[2] => {a:{b}}
[3] => {a:{b:c}}
[4] => {a}
[5] => {b}
[6] => {a}
[7] => {b}
[8] => {c}
[9] => {a{b{c}}}
[10] => {{{d}e}f}
)
[1] => Array
(
[0] => a
[1] => a:b
[2] => a:{b}
[3] => a:{b:c}
[4] => a
[5] => b
[6] => a
[7] => b
[8] => c
[9] => a{b{c}}
[10] => {{d}e}f
)
)
此表达式仅适用于第三级递归。外部文本需要单独处理。 .net正则表达式引擎确实提供递归计数,并且可以支持N层深度。如此处所写,此表达式可能无法按照g
中的预期处理捕获{a:{b}g{h}i}
。
答案 1 :(得分:1)
您还可以构建一个例程,该例程只解析示例字符串中的每个字符并跟踪嵌套深度。
我提供了这个powershell示例,因为我有一个方便的powershell控制台。这只是为了演示该功能的工作原理。
$string = '{a}
{a:b}
a:{b}g{h}ik
{a:{b:c}}
{a}{b}
{a}{b}{c}
{a{b{c}}}{{{d}e}f}
'
$intCount = 0
# split the string on the open and close brackets, the round brackets ensure the squiggly brackets are retained
foreach ($CharacterGroup in $string -split "([{}])") {
write-host $("+" * $intCount)$CharacterGroup
if ($CharacterGroup -match "{") { $intCount += 1 }
if ($CharacterGroup -match "}") { $intCount -= 1 }
if ($intCount -lt 0) {
Write-Host "missing close bracket"
break
} # end if
} # next $CharacterGroup
{
+ a
+ }
{
+ a:b
+ }
a:
{
+ b
+ }
g
{
+ h
+ }
ik
{
+ a:
+ {
++ b:c
++ }
+
+ }
{
+ a
+ }
{
+ b
+ }
{
+ a
+ }
{
+ b
+ }
{
+ c
+ }
{
+ a
+ {
++ b
++ {
+++ c
+++ }
++
++ }
+
+ }
{
+
+ {
++
++ {
+++ d
+++ }
++ e
++ }
+ f
+ }