使用正则表达式解析 tnsnames.ora
我正在尝试使用正则表达式从我的 tnsnames 文件中提取一些信息。我从以下模式开始:
MYSCHEMA *? = *?[\W\w\S\s]*\(主机 *?= *?(?<主机>\w+\s?)\)\s?\(端口 *?= *?(?< ;port>\d+)\s?\)[\W\w\S\s]*\(SERVICE_NAME *?= *?(?
有效当 MYSCHEMA 是文件中唯一的模式时没问题,但是当 MYSCHEMA 之后列出了其他模式时,它会一直匹配到最后一个模式。
此后,我创建了一个新模式:
MYSCHEMA *=\s*\(DESCRIPTION =\s*\(ADDRESS *= *\(PROTOCOL *= *TCP\)\(HOST *= *(?
此模式仅与 MYSCHEMA 匹配,但我必须添加出现在 MYSCHEMA 条目中的每个元素,如果它不包含所有相同的元素,它将与 MYOTHERSCHEMA 不匹配。
理想情况下,我想要一个仅与 MYSCHEMA 条目匹配的模式,并捕获主机、端口和服务名称,以及可选的 (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)
)
)
I am attempting to pull some information from my tnsnames file using regex. I started with the following pattern:
MYSCHEMA *? = *?[\W\w\S\s]*\(HOST *?= *?(?<host>\w+\s?)\)\s?\(PORT *?= *?(?<port>\d+)\s?\)[\W\w\S\s]*\(SERVICE_NAME *?= *?(?<servicename>\w+)\s?\)
which worked fine when MYSCHEMA was the only schema in the file, but when there are other schemas listed after MYSCHEMA it matches all the way to the last schema.
I have since created a new pattern:
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*\)
This pattern matches MYSCHEMA only, but I had to add every element that appeared in MYSCHEMA entry, and it won't match MYOTHERSCHEMA if it does not contain all the same elements.
Ideally, I'd like a pattern that matches MYSCHEMA entry only, and captures HOST, PORT and SERVICE NAME, and optionally (SERVER = DEDICATED) (which I didn't have in the first pattern) to named groups.
Below is the sample tnsnames that I've been using for testing:
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)
)
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用平衡组应该可以做到这一点。并根据您的需要修改开关/外壳。
This should do it, using balanced groups. And modify the switch/case for your needs.
以下正则表达式将解析出各个 TNS 条目,您所要做的就是按照您认为适合名称/值的方式解析每个结果
([\w-]+)\s*=(?:\s| .)+?\)\s*\)\s*\)\s*(?=[\w\-])
示例:https://regexr.com/3r2vn
The following regex will parse out individual TNS entries, and all you have to do is parse each result how you see fit for the names / values
([\w-]+)\s*=(?:\s|.)+?\)\s*\)\s*\)\s*(?=[\w\-])
Example: https://regexr.com/3r2vn
好吧,由于我还没有找到这个问题的令人信服的答案(无意冒犯@Mikael Svenson),所以我只是坚持问题中列出的第二种模式。暂时就足够了,因为 tnsnames.ora 文件始终遵循我们组织内的确切模式。如果 tnsnames.ora 文件格式发生变化,我很可能会采用解析器。
Well, since I haven't found a compelling answer to this issue (no offense @Mikael Svenson), I have just stuck with the second pattern listed in my question. It is sufficient for the time being, as the tnsnames.ora file always follows that exact pattern within our organization. Should the tnsnames.ora file format change, I will most likely adopt a parser.
该表达式使用 address_list 上的一个地址解析架构,等等。
希望这有帮助。
--开始
(?>((?[\n][\s][^(][\w_.]+)[\s]=[\s]))(? >(?[\n\s(]描述[\s=\s](?>(?[\n\s(]*ADDRESS_LIST[\s=\s]*[ \n\s(]地址[\s=\s](?([\n\s(]COMMUNITY)([\n\s(]COMMUNITY[\s=\s]< em>(?[\w.)]+))|())[\s\n](?([\n\s(]协议)([\n\s(]协议[\ s=\s](?[\w.)]+))|())[\s\n](?([\n\s(]HOST)([\n\ s(]HOST[\s=\s](?[\w.)]+))|())[\s\n](?([\n\s(]PORT) )([\n\s(]PORT[\s=\s](?[\w.)]+))|())[\s\n](?()) ())|())))[\s\n](?>(?[\n][\s][(]CONNECT_DATA\s*[=]\s*[ \n](?([(]SID\s[=]\s*)(([(]SID\s*[=]\s*(?[\w.]+) \s*[)]))|())[\s\n](?([(]SERVER\s[=]\s*)(([(]SERVER\s* [=]\s*(?[\w.]+)\s*[)]))|())[\s\n]*(?([(]SERVICE_NAME\s*[=]\s* )(([(]SERVICE_NAME\s*[=]\s*(?[\w.]+)\s*[)]))|())[\s\n](?() )())|())))[\s\n](?())())|())))
*--end
毫无疑问,问题在于写入该文件的形式的倍数。正如您所说的文件必须是唯一的,这是通过使用 TNS_ADMIN 变量来解决的。
This expression parse the schema with one address on address_list, etc.
Hope this helps.
--begin
(?>((?[\n][\s][^(][\w_.]+)[\s]=[\s]))(?>(?[\n\s(]DESCRIPTION[\s=\s](?>(?[\n\s(]*ADDRESS_LIST[\s=\s]*[\n\s(]ADDRESS[\s=\s](?([\n\s(]COMMUNITY)([\n\s(]COMMUNITY[\s=\s](?[\w.)]+))|())[\s\n](?([\n\s(]PROTOCOL)([\n\s(]PROTOCOL[\s=\s](?[\w.)]+))|())[\s\n](?([\n\s(]HOST)([\n\s(]HOST[\s=\s](?[\w.)]+))|())[\s\n](?([\n\s(]PORT)([\n\s(]PORT[\s=\s](?[\w.)]+))|())[\s\n](?())())|())))[\s\n](?>(?[\n][\s][(]CONNECT_DATA\s*[=]\s*[\n](?([(]SID\s[=]\s*)(([(]SID\s*[=]\s*(?[\w.]+)\s*[)]))|())[\s\n](?([(]SERVER\s[=]\s*)(([(]SERVER\s*[=]\s*(?[\w.]+)\s*[)]))|())[\s\n]*(?([(]SERVICE_NAME\s*[=]\s*)(([(]SERVICE_NAME\s*[=]\s*(?[\w.]+)\s*[)]))|())[\s\n](?())())|())))[\s\n](?())())|())))
*--end
Undoubtedly, the problem is the multiple that is in the form of writing that file. As you say the file must be unique, this is solved by using the TNS_ADMIN variable.
我尝试了上面的答案,但没有一个对我有用......
I tried the above answers and none of them worked for me ...