当前位置: 首页 > 知识库问答 >
问题:

如何用python解析oracle jdbc ezconnect

颛孙兴旺
2023-03-14

我试图搜索如何用python解析不同格式的oracle jdbc字符串,但没有找到任何东西。

  • jdbc:oracle:thin:@//hostname.example.ru:1521/database.example.ru
  • jdbc:oracle:thin:@hostname:1521:database

我无法预测下一次我得到的是什么模式。所以我需要使用一些包,它总是能够解析这样的字符串,而不是实现一个更多的自行车。

仍然没有找到任何可以解析零件上的连接字符串而不实际连接到Oracle的包。

这是一个扩展的查询:

^
    jdbc:oracle:thin:
    (
        (?'username'[a-zA-Z0-9]{1,})
        ([\/]
            (?'password'[a-zA-Z0-9]{1,})
        ){0,1}
    ){0,1}
    @
    (
        (\/\/){0,1}
        (?'hostname'[a-zA-Z0-9\.\-]{1,})
        (\:(?'port'\d+)){0,1}
    )
    (\/
        (?'service_name'[a-zA-Z\.\-0-9]{1,}
            (\:
                (?'server_type'[a-zA-Z]{1,})
            ){0,1}
        ){0,1}
        (\/
            (?'instance_name'[a-zA-Z0-9]{1,})
        ){0,1}
    ){0,1}
$

您可以在下面的行中测试它:

jdbc:oracle:thin:@//hostname.example.ru:1521/database.example.ru
jdbc:oracle:thin:@sales-server
jdbc:oracle:thin:@sales-server:3456
jdbc:oracle:thin:@sales-server/sales
jdbc:oracle:thin:@sales-server:80/sales
jdbc:oracle:thin:@sales-server/sales:dedicated/inst1
jdbc:oracle:thin:@sales-server//inst1
jdbc:oracle:thin:@sales-server:1521/sales.us.acme.com
jdbc:oracle:thin:@//sales-server/sales.us.acme.com
jdbc:oracle:thin:@//sales-server.us.acme.com/sales.us.oracle.com
jdbc:oracle:thin:wat@//sales-server.us.acme.com/sales.us.oracle.com
jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com/sales.us.oracle.com
jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com/sales.us.oracle.com:dedicated/instance
jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com//instance
jdbc:oracle:thin:@non-ezconnect-string-test:1521:DATABASE

这段代码是针对Python的:

import re

jdbc_ezconnect = re.compile("^jdbc:oracle:thin:((?P<username>[a-zA-Z0-9]{1,})([\/](?P<password>[a-zA-Z0-9]{1,})){0,1}){0,1}@(?P<ezdb_name>((\/\/){0,1}(?P<hostname>[a-zA-Z0-9\.\-]{1,})(\:(?P<port>\d+)){0,1})(\/(?P<service_name>[a-zA-Z\.\-0-9]{1,}(\:(?P<server_type>[a-zA-Z]{1,})){0,1}){0,1}(\/(?P<instance_name>[a-zA-Z0-9]{1,})){0,1}){0,1})$", re.MULTILINE)

text = [
    "jdbc:oracle:thin:@//hostname.example.ru:1521/database.example.ru",
    "jdbc:oracle:thin:@sales-server",
    "jdbc:oracle:thin:@sales-server:3456",
    "jdbc:oracle:thin:@sales-server/sales",
    "jdbc:oracle:thin:@sales-server:80/sales",
    "jdbc:oracle:thin:@sales-server/sales:dedicated/inst1",
    "jdbc:oracle:thin:@sales-server//inst1",
    "jdbc:oracle:thin:@sales-server:1521/sales.us.acme.com",
    "jdbc:oracle:thin:@//sales-server/sales.us.acme.com",
    "jdbc:oracle:thin:@//sales-server.us.acme.com/sales.us.oracle.com",
    "jdbc:oracle:thin:wat@//sales-server.us.acme.com/sales.us.oracle.com",
    "jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com/sales.us.oracle.com",
    "jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com/sales.us.oracle.com:dedicated/instance",
    "jdbc:oracle:thin:wat/wat@//sales-server.us.acme.com//instance",
    "jdbc:oracle:thin:@hostname:1521:DATABASE"
]

matches = jdbc_ezconnect.search(text[0])

username = matches.group('username')
password = matches.group('password')
ezdb_name = matches.group('ezdb_name')
hostname = matches.group('hostname')
port = matches.group('port')
service_name = matches.group('service_name')
server_type = matches.group('server_type')
instance_name = matches.group('instance_name')


print username, password, ezdb_name, hostname, port, service_name, server_type, instance_name

None None//hostname.example.ru:1521/database.example.ru hostname.example.ru 1521 database.example.ru None None

共有1个答案

屈晨
2023-03-14

我读过关于EZCONNECT语法的oracle文档,并编写了regex来解析它。第二个字符串是标准jdbc模式的简短版本,因此我将这些regexp字符串统一在一个类中,以解析每个变体。

下面是jdbc连接字符串解析器:

# -*- coding: utf-8 -*-

import re


class JDBCParserError(Exception):
    pass


class JDBCParser:
    """
    Класс для распарсивания jdbc-строк.
    """

    # ezonnect patterns
    jdbc_ezconnect = re.compile("^jdbc:oracle:thin:"
                                "((?P<username>[a-zA-Z0-9]{1,})"
                                "([\/](?P<password>[a-zA-Z0-9]{1,})){0,1}){0,1}"
                                "@"
                                "(?P<ezdb_name>((\/\/){0,1}"
                                "(?P<hostname>[a-zA-Z0-9\.\-]{1,})"
                                "(\:(?P<port>\d+)){0,1})"
                                "(\/(?P<service_name>[a-zA-Z\.\-0-9]{1,}"
                                "(\:(?P<server_type>[a-zA-Z]{1,})){0,1}){0,1}"
                                "(\/(?P<instance_name>[a-zA-Z0-9]{1,})){0,1}){0,1})$")

    # jdbc standard pattern - host:port:sid
    jdbc_classic = re.compile("^jdbc:oracle:thin:"
                              "((?P<username>[a-zA-Z0-9]{1,})"
                              "([\/](?P<password>[a-zA-Z0-9]{1,})){0,1}){0,1}"
                              "@"
                              "(?P<connection_string>("
                              "(?P<hostname>[a-zA-Z0-9\.\-]+)"
                              "(\:(?P<port>\d+)))"
                              "(\:(?P<service_name>[a-zA-Z0-9]+)))$")

    username = None
    password = None
    ezdb_name = None
    hostname = None
    port = None
    service_name = None
    instance_name = None

    connection_string = None

    def __init__(self, jdbc_string):
        ezconnect_match = self.jdbc_ezconnect.search(jdbc_string)
        classic_match = self.jdbc_classic.search(jdbc_string)

        if ezconnect_match or classic_match:
            if ezconnect_match:
                self.username = ezconnect_match.group('username')
                self.password = ezconnect_match.group('password')
                self.ezdb_name = ezconnect_match.group('ezdb_name')
                self.hostname = ezconnect_match.group('hostname')
                self.port = ezconnect_match.group('port')
                self.service_name = ezconnect_match.group('service_name')
                self.instance_name = ezconnect_match.group('instance_name')
            if classic_match:
                self.username = classic_match.group('username')
                self.password = classic_match.group('password')
                self.connection_string = classic_match.group('connection_string')
                self.hostname = classic_match.group('hostname')
                self.port = classic_match.group('port')
                self.service_name = classic_match.group('service_name')
        else:
            raise JDBCParserError("JDBC string not recognized")
 类似资料:
  • 问题内容: 我正在尝试解析json对象并遇到问题。 我可以弄清楚如何获得这些值。我可以拿钥匙。请帮忙。 问题答案: 您不再拥有JSON对象,而拥有Python 字典 。遍历字典将产生其密钥。 如果要访问这些值,请为原始词典建立索引或使用返回不同内容的方法之一。

  • 问题内容: 我在包含XML的数据库中有很多行,并且试图编写Python脚本来计算特定节点属性的实例。 我的树看起来像: 如何使用Python访问XML中的属性“1”和“2”? 问题答案: 我建议ElementTree。相同的API还有其他兼容的实现,例如和在标准库本身中。但是,在这种情况下,他们主要添加的是更高的速度-编程的难易程度取决于定义的API 。 首先用 构建 的实例,例如使用函数,或者通

  • 问题内容: 我的项目目前正在python中接收JSON消息,我需要从中获取一些信息。为此,我们将其设置为字符串中的一些简单JSON: 到目前为止,我一直在使用列表生成JSON请求,但是与此相反,我认为我需要使用。但是我没有那么幸运。谁能为我提供一个片段,该片段将在上述示例的输入中返回? 问题答案: 很简单:

  • 问题内容: 是否有任何模块可以将重组文本解析为树模型? docutils或狮身人面像可以这样做吗? 问题答案: Docutils确实包含用于执行此操作的工具。 您可能想要的是位于的解析器 有关所涉及内容的详细信息,请参见此页面。也有一些示例-特别是检查功能,这可能很有趣。

  • 问题内容: 我有以下JSON字符串来自外部输入源: 这是格式错误的JSON字符串(“ id”和“ value”必须用引号引起来),但无论如何我都需要对其进行解析。我已经尝试了simplejson和json- py,但似乎无法将其设置为解析此类字符串。 我正在Google App引擎上运行Python 2.5,因此任何基于C的解决方案(例如python-cjson)都不适用。 除了上面列出的JSON

  • 我正在使用python中的twython库转储我自己的公共推文。数据以json格式下载,请参阅:https://api.twitter.com/1.1/statuses/home_timeline.json 如何逐行打印所有数据,如