将基本Access查询条件表示为正则表达式

reg*_*lus 3 regex ms-access vba

我熟悉Access的查询和过滤条件,但我不确定如何表达类似于正则表达式模式的语句.我想知道是否有人可以帮助将它们与我理解的一些简单例子联系起来.

如果我使用正则表达式来匹配Access等字段,我将如何表达以下语句?示例与此Access Query和Filter Criteria网页上的示例类似.与在Access中一样,大小写不敏感.

  1. "伦敦"

    符合伦敦一词的字符串.

  2. "伦敦"或"巴黎"

    完全匹配伦敦或巴黎的字符串.

  3. 不是"伦敦"

    任何字符串,但伦敦.

  4. 喜欢"S*"

    以字母s开头的任何字符串.

  5. 喜欢"*st"

    任何以字母st结尾的字符串.

  6. 喜欢"*the*dog*"

    包含"the"和"dog"字样的任何字符串,包含之前,之间或结尾处的任何字符.

  7. 像"[AD]*"

    任何以字母A到D开头的字符串,后跟其他任何字符串.

  8. 不喜欢"*伦敦*"

    任何字符串都不包含伦敦这个词.

  9. 不喜欢"L*"

    任何不以L开头的字符串

  10. 喜欢"L*"而不喜欢"伦敦*"

    任何以字母L开头但不以伦敦字开头的字符串.

Ren*_*uis 14

正则表达式比您用于在Access SQL中创建条件的任何模式更强大.如果你限制自己使用这些类型的模式,你将会错过正则表达式的大部分真正有趣的功能.

例如,您无法搜索日期或提取IP地址,简单电子邮件或URL检测或验证,基本参考代码验证(例如询问订单参考代码是否遵循强制编码结构,例如说明等PO123/C456)等

正如@Smandoli所提到的,你最好忘记你对模式匹配的偏见并深入研究正则表达式语言.

我发现掌握正则表达式这本书非常有价值,但是工具最适合用正则表达式模式进行实验; 我使用RegexBuddy,但还有其他工具可用.

基本比赛

现在,关于您的列表,并使用相当标准化的正则表达式语法:

  1. "伦敦"

    符合伦敦一词的字符串.

    ^London$

  2. "伦敦"或"巴黎"

    完全匹配伦敦或巴黎的字符串.

    ^(London|Paris)$

  3. 不是"伦敦"

    任何字符串,但伦敦.

    你匹配^London$并反转结果(NOT)

  4. 喜欢"S*"

    以字母s开头的任何字符串.

    ^s

  5. 喜欢"*st"

    任何以字母st结尾的字符串.

    st$

  6. 喜欢"*the*dog*"

    包含"the"和"dog"字样的任何字符串,包含之前,之间或结尾处的任何字符.

    the.*dog

  7. 像"[AD]*"

    任何以字母A到D开头的字符串,后跟其他任何字符串.

    ^[A-D]

  8. 不喜欢"*伦敦*"

    任何字符串都不包含伦敦这个词.

    反转匹配结果London(你可以使用负面预测,如:
    ^(.(?!London))*$,但我认为它不适用于Access可用的更基本的Regex引擎).

  9. 不喜欢"L*"

    任何不以L开头的字符串

    ^[^L] 正如我们在上面看到的,单个字符的负匹配比整个单词的负匹配更容易.

  10. 喜欢"L*"而不喜欢"伦敦*"

    任何以字母L开头但不以伦敦字开头的字符串.

    ^L(?!ondon).*$

在SQL Criteria中使用Regex

在Access中,创建可直接在SQL查询中使用的用户定义函数非常简单.
要在查询中使用正则表达式匹配,请将此函数放在模块中:

' ----------------------------------------------------------------------'
' Return True if the given string value matches the given Regex pattern '
' ----------------------------------------------------------------------'
Public Function RegexMatch(value As Variant, pattern As String) As Boolean
    If IsNull(value) Then Exit Function
    ' Using a static, we avoid re-creating the same regex object for every call '
    Static regex As Object
    ' Initialise the Regex object '
    If regex Is Nothing Then
        Set regex = CreateObject("vbscript.regexp")
        With regex
            .Global = True
            .IgnoreCase = True
            .MultiLine = True
        End With
    End If
    ' Update the regex pattern if it has changed since last time we were called '
    If regex.pattern <> pattern Then regex.pattern = pattern
    ' Test the value against the pattern '
    RegexMatch = regex.test(value)
End Function
Run Code Online (Sandbox Code Playgroud)

然后,您可以在查询条件中使用它,例如在PartTable表中查找匹配screw 18mm类似Pan Head Screw length 18 mm甚至SCREW18mm等变体的所有部分.

SELECT PartNumber, Description
FROM   PartTable
WHERE  RegexMatch(Description, "screw.*?d+\s*mm")
Run Code Online (Sandbox Code Playgroud)

警告

  • 由于正则表达式匹配使用旧的脚本库,因此正则表达式的语言比.Net中可用于其他编程语言的语言更有限.
    它仍然相当强大,因为它与JavaScript使用的或多或少相同.
    阅读有关VBScript正则表达式引擎的信息,以检查您可以做什么和不能做什么.

  • 更糟糕的是,使用这个库的正则表达式匹配可能相当慢,你应该非常小心,不要过度使用它.

也就是说,它有时非常有用.例如,我使用正则表达式来清理用户输入的数据,并检测具有应该规范化的类似模式的条目.
使用得当,正则表达式可以增强数据的一致性,但要谨慎使用.