Frage

Ich versuche, einige Informationen aus meiner tnsnames Datei mit regex zu ziehen. Ich begann mit dem folgenden Muster:

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

, die gut funktioniert, wenn MYSCHEMA das einzige Schema in der Datei war, aber wenn es andere Schemata aufgelistet nach MYSCHEMA passt es den ganzen Weg bis zum letzten Schema.

Ich habe da ein neues Muster erstellt:

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*\)

Dieses Muster entspricht MYSCHEMA nur, aber ich hatte jedes Element hinzuzufügen, die in MYSCHEMA Eintrag erschienen, und es wird nicht MYOTHERSCHEMA übereinstimmen, wenn sie nicht alle die gleichen Elemente enthalten.

Im Idealfall würde Ich mag ein Muster, dass Streichhölzer MYSCHEMA Eintrag nur, und erfasst HOST, PORT und SERVICE NAME, und gegebenenfalls (SERVER = dedicated) an genannten Gruppen (die ich nicht in dem ersten Muster hatte).

Im Folgenden finden Sie die Probe tnsnames, dass ich für die Prüfung wurde mit:

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)
    )
  )
War es hilfreich?

Lösung 3

Nun, da habe ich keine zwingende Antwort auf diese Frage (kein Vergehen @Mikael Svenson) gefunden, habe ich nur mit dem zweiten Muster in meiner Frage aufgeführt stecken. Es genügt vorerst, wie die Datei tnsnames.ora folgt immer, dass die genauen Mustern innerhalb unserer Organisation. Sollte die tnsnames.ora Dateiformat ändern, werde ich höchstwahrscheinlich einen Parser übernehmen.

Andere Tipps

Das sollte es tun, ausgeglichene Gruppen verwenden. Und ändern Sie den Schalter / Fall für Ihre Bedürfnisse.

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)
        )
      )
    ";
}

Die folgenden Regex werden einzelne TNS-Einträge analysieren, und alles, was Sie tun müssen, ist jedes Ergebnis zu analysieren, wie Sie fit für die Namen / Wert

siehe

([\w-]+)\s*=(?:\s|.)+?\)\s*\)\s*\)\s*(?=[\w\-])

Beispiel: https://regexr.com/3r2vn

analysierte Dieser Ausdruck das Schema mit einer Adresse auf ADDRESS_LIST usw. Hoffe, das hilft.

- beginnen (?> ((? [\ N] [\ s] [^ (] [\ w _.] +) [\ S] = [\ s] )) (?> (? [\ n \ n (] BESCHREIBUNG [\ s = \ s] (> (? [\ n \ n (] * ADDRESS_LIST [\ s = \ s] * [\ n \ s (] ADDRESS [\ s = \ s] (? ([\ n \ n (] COMMUNITY) ([\ n \ n (] COMMUNITY [\ s = \ s] ( ? [\ w).] +)) | ()) [\ s \ n] (([\ n \ n (] PROTOKOLL) ([\ n \ n (] PROTOKOLL [\ s = \ s] ] +)) ([\ w?.) | ()) [\ s \ n] (([\ n \ n (] HOST) ([\ n \ n (] HOST [\ s = \ s] +)) ([\ w.?)] | ()) [\ s \ n] (([\ n \ n (] PORT) ([ \ n \ n (] PORT [\ s = \ s] ([\ w)] +?.)) | ()) [\ s \ n] (()) ()) |? ()))) [\ s \ n] (> ([\ n] [\ s] [(] CONNECT_DATA \ s * [=] \ s * [\ n] < em> (? ([(] SID \ s [=] \ s *) (([(] SID \ s * [=] \ s * (? [\ w.] +) \ s * [ )])) | ()) [\ s \ n] (([(] SERVER \ s [=] \ s *) (([(] SERVER \ s * [=] \ s * \ s * [)])) ([\ w.] +?) | ()) [\ s \ n] * (([(] SERVICE_NAME \ s * [=] \ s *) (([ (] SERVICE_NAME \ s * [=] \ s * ([\ w] +) \ s * [?.)])) | ()) [\ s \ n] (()) ()) | ()))) [\ s \ n] (()) ()) | ()))) * - Ende

Zweifellos ist das Problem das Mehrfach, die zu schreiben, die Datei in der Form ist. Wie Sie die Datei sagen muss eindeutig sein, dies mit der TNS_ADMIN Variable gelöst wird.

habe ich versucht, die oben genannten Antworten und keiner von ihnen arbeitete für mich ...

    [DebuggerDisplay("Name {Name} Host:{Host} ServiceName:{ServiceName} Port:{Port}")]
    public class TnsEntry
    {
        public string Name { get; set; }
        public string Host { get; set; }
        public string Port { get; set; }
        public string ServiceName { get; set; }
    }


   public class TnsNamesFileParser
   {
    public string TNSNamesContents { get; set; }

    public TnsNamesFileParser()
    {
    }

    public TnsNamesFileParser(string locationAndNameOfTnsNamesFile)
    {
        TNSNamesContents = System.IO.File.ReadAllText(locationAndNameOfTnsNamesFile);
    }

    public List<TnsEntry> Parse()
    {
        return Parse(TNSNamesContents);
    }

    public List<TnsEntry> Parse(string TNSNamesContents)
    {
        string TNSPattern = @"([\w -] +)\s *= (?:\s |.) +?\)\s *\)\s *\)\s * ((?=[\w\-])|(?=$))";

        Regex reTns = new Regex(TNSPattern, RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
        MatchCollection matchCollection = reTns.Matches(TNSNamesContents);

        var TnsEntries = new List<TnsEntry>();

        foreach (Match match in matchCollection)
        {
            var tnsEntry = new TnsEntry();
            string matchedValue = match.Value.Trim();

            tnsEntry.Name = Regex.Match(matchedValue, @"^([^\s]+)", RegexOptions.IgnoreCase)?.Value.Trim();
            tnsEntry.Host = Regex.Match(matchedValue, "(?<=HOST.+=) ([^)]*)", RegexOptions.IgnoreCase)?.Value.Trim();
            tnsEntry.Port = Regex.Match(matchedValue, "(?<=PORT.+=) ([^)]*)", RegexOptions.IgnoreCase)?.Value.Trim();
            tnsEntry.ServiceName = Regex.Match(matchedValue, "(?<=SERVICE_NAME.+=) ([^)]*)", RegexOptions.IgnoreCase)?.Value;

            TnsEntries.Add(tnsEntry);

        }

        return TnsEntries;
    }
  }

//Test Code: 

string testdata =@"
        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)
        )
        )";
 [Test]
 public void ParseTNSFileEntries()
 {

  var tnsNamesFileParser = new TnsNamesFileParser();
  var entries =  tnsNamesFileParser.Parse(testdata);


 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top