如何在PostgreSQL中将包含数值的字符串拆分为三个部分?

时间:2015-07-26 00:14:45

标签: regex postgresql pattern-matching

我想使用regexp_matches()拆分可能包含数值的给定字符串。它应该标识第一次出现的包含可选符号和可选小数位的数值。还应返回不匹配的部分 - 作为数组的第一个和最后一个位置。

一些示例输入和预期输出值:

'hello+111123.454545world' -> {hello,+111123.454545,world}
'he-lo+111123.454545world' -> {he-lo,+111123.454545,world}
'hel123.5lo+111123.454545world' -> {hel,123.5,lo+111123.454545world}
'hello+111123.454545world' -> {hello,+111123.454545,world}
'hello+111123.454545world' -> {hello,+111123.454545,world}
'1111.15' -> {"",1111.15,""}
'-.234' -> {"",-.234,""}
'hello-.234' -> {hello,-.234,""}

我在以下由'TODO'表示的表达式中遇到匹配组的第一部分时出现问题。它应该匹配任何无法识别为数值的东西。

select regexp_matches('input', '(TODO)((?:\+|-)?(?:\d*(?:(?:\.)?\d+)))(.*)')

由'(TODO)'表示的匹配组需要是第二个匹配组中正则表达式的否定。 (因为结果需要退回)。匹配数值的正则表达式工作正常,我需要的是如何匹配字符串的第一部分,而不是数值。

4 个答案:

答案 0 :(得分:3)

def setupUi(self, Form):
    L = ["Forest", "Lake", "Desert"]
    changeMatrix = [[11, 12, 13], [21, 22, 23], [31, 32, 33]]
    count_i = 1

    #Form
    Form.setObjectName(_fromUtf8("Form"))
    Form.resize(600, 600)

    #Graphics View
    self.graphicsView = QtGui.QGraphicsView(Form)
    self.graphicsView.setGeometry(QtCore.QRect(50, 50, 400, 400))
    self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

    #Pen, Brush, Scene
    pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 3, QtCore.Qt.SolidLine)
    brush = QtGui.QBrush(QtGui.QColor(184, 36, 238))
    scene = QtGui.QGraphicsScene()

    #Boxes & Labels
    count_valid = 0
    for i in changeMatrix:
        count_j = 1
        for j in i:
            if j <> 0 and count_i <> count_j:
                textitem_L = scene.addText(L[count_j-1])
                textitem_R = scene.addText(L[count_i-1])
                textitem_L.setPos(0, count_valid*50)
                textitem_R.setPos(300, count_valid*50)
                rect_L = scene.addRect(50, count_valid*50, 25, 25, pen, brush)
                rect_R = scene.addRect(250, count_valid*50, 25, 25, pen, brush)
                rect_L.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsSelectable | QtGui.QGraphicsItem.ItemIsFocusable | QtGui.QGraphicsItem.ItemSendsGeometryChanges)
                rect_R.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsSelectable | QtGui.QGraphicsItem.ItemIsFocusable | QtGui.QGraphicsItem.ItemSendsGeometryChanges)
                rect_L.setAcceptsHoverEvents(True)
                rect_R.setAcceptsHoverEvents(True)
                count_valid += 1
            count_j += 1
        count_i += 1

    self.graphicsView.setScene(scene)

    #Form
    Form.setWindowTitle(_translate("Form", "MoveRect", None))
  • 第一场比赛:regexp_matches(input, '(^.*?)([+-]?\d*\.?\d+)(.*$)') AS result_arr
    使用(^.*?)锚定到字符串的开头。 non-greedy quantifier *?至关重要 它实际上不必^,因为正则表达式的其余部分是 greedy 。所以第一部分是仍然,由其他人定义。

  • 第二场比赛:be the negation of the regular expression in the second match group
    我有点简化你的表达。特别是字符类([+-]?\d*?\.?\d+)比非捕获括号[+-]中的两个分支更短更快。 Non-capturing parentheses很重要。 (你已经有了。)
    @maraca评论后简化(?:\+|-)

  • 第3场比赛:\d*
    使用(.*$)锚定到字符串的末尾。对于最后一场比赛,使量词贪婪

带有扩展测试用例的

SQL Fiddle

答案 1 :(得分:1)

我认为这个正则表达式会给你你想要的东西: /'(.*?)([+\-]?[0-9\.]+)(.*?)'/g

示例:https://regex101.com/r/nF5qV7/1

答案 2 :(得分:0)

试试这个:

(.*?)((?:\+|-)?(?:\d*(?:(?:\.)?\d+)))(.*)

答案 3 :(得分:0)

这是正确的正则表达式,假设点之后必须至少有一个数字:

(.*?)([+-]?[0-9]*\.[0-9]+)(.*)

或者使用可选的点,匹配1.,.7,+ 8,-4,0.0,42,...

(.*?)([+-]?(?:\.[0-9]+|[0-9]+\.?[0-9]*))(.*)