mysql中regexp表达式中的求值顺序

时间:2017-10-24 10:53:17

标签: mysql regex string

我试图在mysql数据库中根据男性姓氏的正则表达式找到女性姓氏。我差不多完成了它,但我的正则表达式中仍然有一个错误,我无法弄清楚它是什么。括号[]中的许多可选字符是由于非常混乱的数据库引起的。我已经尝试过在线调试器,但没有运气。

来源:

从字符串转换:

SELECT * FROM `female`
    WHERE (sex= 'žena')
      AND (surname REGEXP
        '^[rř].{0,1}[eéě][zž].{0,1}[nň][aeiouáéíóúěyý]*[cč][aeiouáéíóúěyý]*[k].*$')

我的查询:

Řezníčková
Řezníčková
Řezníčková
Řezníčková

所需的输出:

Řezníčková
Řezníková
Řezníková
Řezníčková

当前输出:

^[rř].{0,1}[eéě]

正则表达式解释:(某种方式在mysql regexp中的行为与其他系统中常见的不同,所以我不得不训练我的解决方案):

[zž].{0,1}[nň]

roř应该在句子的开头

在第二个位置应该是元音e或é或ě

。{0,1}没有它就无法正常工作

[nň][aeiouáéíóúěyý]*

两个非元音之间总是。{0,1}否则表达式不起作用

[aeiouáéíóúěyý]*

如果非元音后是元音,则不需要在这些规则之间使用其他*

[cč]
[k]

如果元音外观不是姓氏中的第一个,则它总是可选的

.*$

任何其他非元音都是强制性的

Option Explicit


Sub SaveShtsAsBook()
Dim Sheet As Worksheet, SheetName$, MyFilePath$, N&
MyFilePath$ = ActiveWorkbook.Path & "\" & _
Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 4)

With Application
    .ScreenUpdating = False
    .DisplayAlerts = False
     '      End With
    On Error Resume Next '<< a folder exists
    MkDir MyFilePath '<< create a folder
    For Each Sheet In Worksheets
        If Sheet.Name <> "Overall" Or Sheet.Name <> "Staff" Then
        Sheet.Copy
            With ActiveWorkbook
                With .ActiveSheet
                    [A1].Select
                    SheetName = ActiveSheet.Name
                End With
                .SaveAs Filename:=MyFilePath _
                & "\" & SheetName & ".xlsx"
                .Close SaveChanges:=True
            End With
            .CutCopyMode = False
        End If
    Next
End With
Sheet1.Activate
End Sub

因为我们正在寻找男性的女性姓氏,所以我们期待女性姓氏更长,并以某种方式以男性姓氏为基础。在女性姓氏结尾处还有3-5个字符。

问题:

为什么输出中的姓氏'Řezníková'在表达式中是c或oblig义务?有没有办法强制regexp评估表达式,而不是应用优先级?我怀疑[cč]以某种方式被*。

压制

我非常感谢你们提出任何建议。

1 个答案:

答案 0 :(得分:0)

MySQL的正则表达式不理解多字节字符(č等)。而不是检查c(十六进制63)或č(十六进制C48D),[cč]检查以下3个字节中的任何一个:63 C4 8D 。由于C4是常见的第一个字节,因此匹配。

MariaDB的正则表达式确实如此。所以切换到这是一个答案。

使用HEX(surname) REGEXP ... 可能可以替代MySQL,但正则表达式会相当混乱。要构建十六进制版本,您需要(63|C48D)当前[cč]

转换为LIKE 可能是的替代选择。请注意,大多数排序规则中e = é = ě,因此除e之外无需提及任何内容。 (第二个想法,LIKE似乎不太可能,因为它没有什么可以模拟&#34;字符类&#34;如[aeiouáéíóúěyý]。)

请提供SHOW CREATE TABLE

十六进制正则表达式类似于

^(72|C599)(..)?(65|C3A9|C49B)(7A|C5BE)(..)?(等)但我想这也行不通,因为(..)?表示0或1个单字节(2个十六进制),但你需要0或1 字符< / em>的。所以需要替换为([4-7].|C...)?。等等。