Python/RE 将 tnsnames.ora 解析为连接字符串
Python/RE Parse tnsnames.ora into connection strings
我正在开发一个函数来从 tnsnames.ora 检索特定的连接字符串并设置它们以供 cx_Oracle 稍后使用。我决定学习“正则表达式”是正确的方法,但它给我带来的麻烦比我想象的要多。感谢任何帮助将每个条目折叠成一行且没有空格并匹配条目的帮助。
来自 tnsnames.ora 个文件的片段:
ExPRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExPRD)
)
)
ExQAT =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExQAT)
)
)
ExTST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExTST)
)
)
想要的结果,设置以下全局变量:
exprd_cs = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= whatever.com)(PORT=0000))(ADDRESS=(PROTOCOL=TCP)(HOST= whatever2.com)(PORT=0000))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ExPRD)))
extst_cs = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= whatever.com)(PORT=0000))(ADDRESS=(PROTOCOL=TCP)(HOST= whatever2.com)(PORT=0000))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ExTST)))
Python 脚本:
import re
tns_file = path/tnsnames.ora
def Read_File(FILENAME, LINE):
try:
if LINE == 'NO':
with open(FILENAME) as opened_file:
file_string = opened_file.read()
if LINE == 'YES':
with open(FILENAME) as opened_file:
file_string = opened_file.readline()
except IOError as e:
print("File Failed to Open;", e)
raise e
except Exception as e:
print("Read File Failed;", e)
raise e
return file_string
def Get_TNS_Config():
global exprd_cs
global extst_cs
tns_config = Read_File(tns_file, 'YES')
(找到一种将配置条目折叠成单行且无空格的方法)
(continued...)
for match in re.finditer(r'<db>=<db_cs>', tns_config):
if match.group(1) == ‘ExPRD’:
exprd_cs = match.group(2)
if match.group(1) == ‘ExTST’:
extst_cs = match.group(2)
Get_TNS_Config()
获取变量的一种方法可能是首先使用 sub 创建没有空格的行和一个正则表达式,该正则表达式匹配一次或多次空白字符,并带有否定前瞻性断言后面的内容不是ExPRD
、ExQAT
或 ExTST
在行首并替换为空字符串:
\s+(?!^Ex(?:PRD|QAT|TST))
然后使用 finditer 使用 2 个捕获组 ^(Ex(?:PRD|QAT|TST))(.*)
,您可以在其中检查第一个捕获组并相应地分配第二个捕获组。
例如
tns_config = """ExPRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExPRD)
)
)
ExQAT =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExQAT)
)
)
ExTST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExTST)
)
)"""
regex = r"\s+(?!^Ex(?:PRD|QAT|TST))"
result = re.sub(regex, '', tns_config, 0, re.MULTILINE)
exprd_cs = ""
extst_cs = ""
if result:
for match in re.finditer(r'^(Ex(?:PRD|QAT|TST))(.*)', result, re.MULTILINE):
if match.group(1) == 'ExPRD':
exprd_cs = match.group(2)
if match.group(1) == 'ExTST':
extst_cs = match.group(2)
print(exprd_cs)
print(extst_cs)
我正在开发一个函数来从 tnsnames.ora 检索特定的连接字符串并设置它们以供 cx_Oracle 稍后使用。我决定学习“正则表达式”是正确的方法,但它给我带来的麻烦比我想象的要多。感谢任何帮助将每个条目折叠成一行且没有空格并匹配条目的帮助。
来自 tnsnames.ora 个文件的片段:
ExPRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExPRD)
)
)
ExQAT =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExQAT)
)
)
ExTST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExTST)
)
)
想要的结果,设置以下全局变量:
exprd_cs = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= whatever.com)(PORT=0000))(ADDRESS=(PROTOCOL=TCP)(HOST= whatever2.com)(PORT=0000))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ExPRD)))
extst_cs = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= whatever.com)(PORT=0000))(ADDRESS=(PROTOCOL=TCP)(HOST= whatever2.com)(PORT=0000))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ExTST)))
Python 脚本:
import re
tns_file = path/tnsnames.ora
def Read_File(FILENAME, LINE):
try:
if LINE == 'NO':
with open(FILENAME) as opened_file:
file_string = opened_file.read()
if LINE == 'YES':
with open(FILENAME) as opened_file:
file_string = opened_file.readline()
except IOError as e:
print("File Failed to Open;", e)
raise e
except Exception as e:
print("Read File Failed;", e)
raise e
return file_string
def Get_TNS_Config():
global exprd_cs
global extst_cs
tns_config = Read_File(tns_file, 'YES')
(找到一种将配置条目折叠成单行且无空格的方法)
(continued...)
for match in re.finditer(r'<db>=<db_cs>', tns_config):
if match.group(1) == ‘ExPRD’:
exprd_cs = match.group(2)
if match.group(1) == ‘ExTST’:
extst_cs = match.group(2)
Get_TNS_Config()
获取变量的一种方法可能是首先使用 sub 创建没有空格的行和一个正则表达式,该正则表达式匹配一次或多次空白字符,并带有否定前瞻性断言后面的内容不是ExPRD
、ExQAT
或 ExTST
在行首并替换为空字符串:
\s+(?!^Ex(?:PRD|QAT|TST))
然后使用 finditer 使用 2 个捕获组 ^(Ex(?:PRD|QAT|TST))(.*)
,您可以在其中检查第一个捕获组并相应地分配第二个捕获组。
例如
tns_config = """ExPRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExPRD)
)
)
ExQAT =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExQAT)
)
)
ExTST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever.com)(PORT = 0000))
(ADDRESS = (PROTOCOL = TCP)(HOST = whatever2.com)(PORT = 0000))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ExTST)
)
)"""
regex = r"\s+(?!^Ex(?:PRD|QAT|TST))"
result = re.sub(regex, '', tns_config, 0, re.MULTILINE)
exprd_cs = ""
extst_cs = ""
if result:
for match in re.finditer(r'^(Ex(?:PRD|QAT|TST))(.*)', result, re.MULTILINE):
if match.group(1) == 'ExPRD':
exprd_cs = match.group(2)
if match.group(1) == 'ExTST':
extst_cs = match.group(2)
print(exprd_cs)
print(extst_cs)