Python / RE将tnsnames.ora解析为连接字符串

时间:2018-10-05 17:22:40

标签: python regex

我正在开发一个函数,用于从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()

1 个答案:

答案 0 :(得分:0)

获取变量的一种方法是首先使用sub和正则表达式创建不带空格的行,该正则表达式匹配空白字符一次或多次,并带有负向超前,表示后面不是{{ 1}},question_date_per_answerExPRD在行的开头,并替换为空字符串:

ExQAT

Regex demo

然后使用finditer使用2个捕获组ExTST,您可以在其中检查第一个捕获组并相应地分配第二个捕获组。

Regex demo

请参见Python demo

例如

\s+(?!^Ex(?:PRD|QAT|TST))