c# - 使用正则表达式解析 tnsnames.ora

标签 c# .net regex oracle tnsnames

我正在尝试使用正则表达式从我的 tnsnames 文件中提取一些信息。我从以下模式开始:

MYSCHEMA *? = *?[\W\w\S\s]*\(HOST *?= *?(?<host>\w+\s?)\)\s?\(PORT *?= *?(?<port>\d+)\s?\)[\W\w\S\s]*\(SERVICE_NAME *?= *?(?<servicename>\w+)\s?\)

当 MYSCHEMA 是文件中唯一的模式时,它工作正常,但是当 MYSCHEMA 之后列出其他模式时,它一直匹配到最后一个模式。

我已经创建了一个新模式:

MYSCHEMA *=\s*\(DESCRIPTION =\s*\(ADDRESS *= *\(PROTOCOL *= *TCP\)\(HOST *= *(?<host>\w+)\)\(PORT *= *(?<port>\d+)\)\)\s*\(CONNECT_DATA *=\s*(?<serverdedicated>\(SERVER *= *DEDICATED\))\s*\(SERVICE_NAME *= *(?<servicename>[\w\.]+) *\)\s*\)\s*\)

此模式仅匹配 MYSCHEMA,但我必须添加出现在 MYSCHEMA 条目中的每个元素,如果它不包含所有相同的元素,它将不会匹配 MYOTHERSCHEMA。

理想情况下,我想要一个只匹配 MYSCHEMA 条目的模式,并捕获 HOST、PORT 和 SERVICE NAME,并且可选地 (SERVER = DEDICATED)(我在第一个模式中没有)到命名组。

下面是我一直用于测试的示例 tnsnames:

SOMESCHEMA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = REMOTEHOST)(PORT = 1234))
    )
    (CONNECT_DATA = (SERVICE_NAME = REMOTE)
    )
  )

MYSCHEMA =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = MYHOST)(PORT = 1234))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = MYSERVICE.LOCAL )
    )
  )

MYOTHERSCHEMA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = MYHOST)(PORT = 1234))
    )
    (CONNECT_DATA = 
      (SERVICE_NAME = MYSERVICE.REMOTE)
    )

  )

SOMEOTHERSCHEMA = 
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = LOCALHOST)(PORT = 1234))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = LOCAL)
    )
  )

最佳答案

这应该可以做到,使用平衡组。并根据您的需要修改开关/外壳。

class TnsRegex
{
    public void Test()
    {
        Regex reTns = new Regex(_pattern, RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
        MatchCollection matchCollection = reTns.Matches(_text);

        foreach (Match match in matchCollection)
        {
            foreach (Capture capture in match.Groups["Settings"].Captures)
            {
                string[] setting = capture.Value.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                string key = setting[0].Trim();
                string val = setting[1].Trim();
                if (val.Contains("(")) continue;
                switch (key)
                {
                    case "HOST":
                        break;
                    case "PORT":
                        break;
                    case "SERVICE_NAME":
                        break;
                    case "SERVER":
                        break;
                }
                Console.WriteLine(key + ":" + val);
            }
        }
    }
    string _pattern = @"
        MYSCHEMA\s+=\s+\(
        [^\(\)]*
        (
                    (
                                (?<Open>\()
                                [^\(\)]*
                    )+
                    (
                                (?<Settings-Open>\))
                                [^\(\)]*
                    )+
        )*
        (?(Open)(?!))
    \)";

    string _text = @"
    MYSCHEMA =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = MYHOST)(PORT = 1234))
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = MYSERVICE.LOCAL )
        )
      )

    SOMESCHEMA =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = REMOTEHOST)(PORT = 1234))
        )
        (CONNECT_DATA = (SERVICE_NAME = REMOTE)
        )
      )
    ";
}

关于c# - 使用正则表达式解析 tnsnames.ora,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3549863/

相关文章:

c# - 保存完数据后如何清除缓存?

c# - 在没有 t4 代码生成器的情况下创建 Entity Framework (如 vs 2010)

c# - 查找虚方法的原始实现

.net - C++/CLI 中的 Lambda 表达式

正则表达式无法对两个匹配项使用相同的字符

java : regular expression for ipconfig

正则表达式可选组解析

c# - 我如何计算和创建三角形的位置?

C# 使用 LINQ 将 ID 列表与对象列表中的每个 ID 进行比较

c# - 请问 GC.SuppressFinalize 有什么实质性影响吗?