创建一个名为http://vbfiddle.net的网站,在浏览器中实现并测试@ ctwheel的VBScript解决方案(MS IE 10+,安全性设置为“中”),该网站上的说明如何为您设置如果你想要玩 - 从jsfiddle.net的这个链接获取代码复制和粘贴到vbfiddle.net:https://jsfiddle.net/hcwjhmg9/ [ vbfiddle.net目前没有“保存”功能]),我发现@ ctwheel的VBScript RegEx运行成功,即使对于我给出的第3个示例行,但是当@ ctwheel的VBScript RegEx用于VBS for VAP for Microsoft Access 2016时,对于从数据库读取的记录“相同的“值,第三个子组只返回”Ray“,对于我给出的第三个示例行,它应该返回”Ray,CFP“,就像它在vbfiddle.net中一样。
我终于想到迭代数据库返回的字符串值的每个字符(在Microsoft Access中的VBA中),并将它与我直接输入的视觉等效字符串值的每个字符的迭代进行比较。代码(在Microsoft Access中的VBA中)。我得到以下结果:
First Name and Last Name: "G.L. (Pete) Ray, CFP"
--- 1st Text chars: "71 46 76 46 32 40 80 101 116 101 41 32 82 97 121 44"
(Read value from database, appears same as below when Debug.Print is called on it)
--- 2nd Text chars: "71 46 76 46 32 40 80 101 116 101 41 32 82 97 121 44 32 67 70 80" (Typed by keyboard into a string within the code)
'G.L. (Pete) Ray,'
strProperName>objSubMatch: "G.L."
strProperName>objSubMatch: "Pete"
strProperName>objSubMatch: "Ray,"
Matching record(s): 3 of 1132 record(s).
我正在运行的RegEx正在针对“1st Text Chars
”示例运行,并返回“Ray”,用于先前给定的第3个示例行的第3个子组:“G.L. (Pete) Ray, CFP
”。但是,如果我对第二个类型的RegEx运行 - 直接输入代码 - “2nd Text chars
”示例,第三个子组将按照预期在VBA for Microsoft Access 2016中返回“Ray,CFP”。
我现在正在使用@ctwheels提供的RegEx:
^([^(]+?)\s*\(\s*([^)]*?)\s*\)\s*(.*)
有人可以解释这里发生了什么吗? 1)为什么从数据库返回的字符与使用键盘输入字符串返回的字符不同,通过直观地读取和复制它? 2)当如何直接从数据库中读取值时,如何使“1st Text Chars
”字符/字符串序列的RegEx返回正确的第3个子组:“Ray, CFP
”?
原始问题(上面更新的问题):
我在使用带有Regex引擎的Microsoft Access 2016的VBA中遇到问题我相信5.5 for VBScript。
这是我正在使用的正则表达式:
"(.*)\((.*)(\))(.*)"
我正在尝试解析字符串(分别在每个新行上):
Lawrence N. (Larry) Solomon
James ( Jim ) Alleman
G.L. (Pete) Ray, CFP
分为:
"Lawrence N.", "Larry", ")", "Solomon"
"James", "Jim", ")", "Alleman"
"G.L.", "Pete", ")", "Ray, CFP"
或者(最好)进入:
"Lawrence N.", "Larry", "Solomon"
"James", "Jim", "Alleman"
"G.L.", "Pete", "Ray, CFP"
其中引号中的部分(以逗号分隔)是子匹配中返回的部分(不含引号)
我使用以下代码:
' For Proper Name (strProperName):
With objRegex
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = "(.*)\((.*)(\))(.*)"
'([\s|\S]*) work around to match every character?
'".*\(([^\s]*)[\s]*\(" '_
''& "[\"
'[\(][\s]*([.|^\w]*)[\s]*\)"
' "[\s]*(.*)[\s]*\("
' does same as below except matches any or no whitespace preceding any characters,
' and returns the following characters up to an opening parenthesis ("(") but excluding it,
' as the first subgroup
' "(.*)[\s]*\("
' does same as below except matches any whitespace or no whitespace at all followed by an opening parenthesis ("(")
' and returns the preceding characters as the first subgroup
' "(.*)\("
' matches all characters in a row that end with an open parenthesis, and returns all of these characters in a row
' excluding the following open parenthesis as the first subgroup
' "(.*?\(\s)"
' "[^\(]*"
' this pattern returns every character that isn't an opening parenthesis ("("), and when
' it matches an open parenthesis, it does not return it or any characters after it
' "[\(\s](.*)\)"
' this pattern extracts everything between parenthesis in a line as its first submatch
' "(?<=\().*"
' "[^[^\(]*][.*]"
' "(\(.*?\))"
' "(\(.*?\))*([^\(].*[^\)])"
End With
If objRegex.Test(strFirstNameTrimmed) Then
'Set strsMatches = objRegex.Execute(rs.Fields("First Name"))
Set strsMatches = objRegex.Execute(strFirstNameTrimmed)
Debug.Print "2:'" & strsMatches(0).Value & "'"
If strsMatches(0).SubMatches.Count > 0 Then
For Each objSubMatch In strsMatches(0).SubMatches
Debug.Print " strProperName>objSubMatch: """ & objSubMatch & """" 'Result: 000, 643, 888"
strProperName = objSubMatch
Next objSubMatch
End If
Else
strProperName = "*Not Matched*"
End If
在调试窗口/“立即窗口”中生成以下输出,因为它在VBA中已知,由(Ctrl + G)调出:
------------------------
First Name and Last Name: "Lawrence N. (Larry) Solomon"
2:'Lawrence N. (Larry)'
strProperName>objSubMatch: "Lawrence N. "
strProperName>objSubMatch: "Larry"
strProperName>objSubMatch: ")"
strProperName>objSubMatch: ""
Extracted Nick Name: "Larry"
Extracted Proper Name: ""
First Name and Last Name: "James ( Jim ) Alleman"
2:'James ( Jim )'
strProperName>objSubMatch: "James "
strProperName>objSubMatch: " Jim "
strProperName>objSubMatch: ")"
strProperName>objSubMatch: ""
Extracted Nick Name: "Jim"
Extracted Proper Name: ""
First Name and Last Name: "G.L. (Pete) Ray, CFP"
2:'G.L. (Pete) Ray,'
strProperName>objSubMatch: "G.L. "
strProperName>objSubMatch: "Pete"
strProperName>objSubMatch: ")"
strProperName>objSubMatch: " Ray,"
Extracted Nick Name: "Pete"
Extracted Proper Name: " Ray,"
Matching record(s): 3 of 1132 record(s).
答案 0 :(得分:1)
^
([^(]+?)
在行首处断言位置(
将\s*
除\(
之外的任何字符捕获一次或多次,但尽可能少捕获到捕获组1 (
匹配任意数量的空白字符\s*
按字面意思匹配([^)]*?)
)
匹配任意数量的空白字符\s*
将\(
除(
之外的任何字符捕获一次或多次,但尽可能少捕获到捕获组2 \s*
匹配任意数量的空白字符(.*)
按字面意思匹配["Lawrence N.", "Larry", "Solomon"]
["James", "Jim", "Alleman"]
["G.L.", "Pete", "Ray, CFP"]
fn2
匹配任意数量的空白字符def _fn2():
do_something_else()
@transaction(True)
def fn1(x=False):
if x:
return _fn2()
do_something()
fn2 = transaction(True)(_fn2)
将其余部分捕获到捕获组3 结果:
{{1}}
答案 1 :(得分:1)
你应该能够避免使用正则表达式,如果这是你的事情。
我对昵称包含在“()”中的测试数据做了一些假设。除此之外,代码应该是直截了当的,我希望。如果没有,请随意提问。还包含一个名为Test
的测试例程。
Public Function ParseString(InputString As String) As String
On Error GoTo ErrorHandler:
Dim OutputArray As Variant
Const DoubleQuote As String = """"
'Quick exit, if () aren't found, then just return original text
If InStr(1, InputString, "(") = 0 Or InStr(1, InputString, ")") = 0 Then
ParseString = InputString
Exit Function
End If
'Replace the ) with (, then do a split
OutputArray = Split(Replace(InputString, ")", "("), "(")
'Check the array bounds and output accordingly
'If there can only ever be 3 (0 - 2) elements, then you can change this if statement
If UBound(OutputArray) = 2 Then
ParseString = DoubleQuote & Trim$(OutputArray(0)) & DoubleQuote & ", " & _
DoubleQuote & Trim$(OutputArray(1)) & DoubleQuote & ", " & _
DoubleQuote & Trim$(OutputArray(2)) & DoubleQuote
ElseIf UBound(OutputArray) = 1 Then
ParseString = DoubleQuote & Trim$(OutputArray(0)) & DoubleQuote & ", " & _
DoubleQuote & Trim$(OutputArray(1)) & DoubleQuote
Else
ParseString = DoubleQuote & Trim$(OutputArray(LBound(OutputArray))) & DoubleQuote
End If
CleanExit:
Exit Function
ErrorHandler:
ParseString = InputString
Resume CleanExit
End Function
Sub Test()
Dim Arr() As Variant: Arr = Array("Lawrence N. (Larry) Solomon", "James ( Jim ) Alleman", "G.L. (Pete) Ray, CFP")
For i = LBound(Arr) To UBound(Arr)
Debug.Print ParseString(CStr(Arr(i)))
Next
End Sub
<强>结果
"Lawrence N.", "Larry", "Solomon"
"James", "Jim", "Alleman"
"G.L.", "Pete", "Ray, CFP"
答案 2 :(得分:0)
正则表达式:\s*[()]\s*
详细说明:
[()]
匹配任何空白字符零和无限次(
匹配列表中的单个字符)
或Dim str As String
str = "Lawrence N. (Larry) Solomon"
Set re = CreateObject("VBScript.RegExp")
re.Global = True
re.Pattern = "\s*[()]\s*"
re.MultiLine = True
Dim arr As Variant
arr = Strings.Split(re.Replace(str, vbNullChar), vbNullChar)
For Each Match In arr
Debug.Print (Match)
Next
VBA代码:
Lawrence N.
Larry
Solomon
输出:
# configuration.py
...
def __init__(self):
"""Constructor"""
# Default Base url
self.host = "http://petstore.swagger.io:80/v2"