I have several strings. Examples:
我有几个字符串。例子:
PK - Package
EA -- Each
AB - Solo Container
TB -- Tube
I need to get just the text to the right of the last dash. Sometimes there may be a single dash, sometimes there may be 2 dashes (shouldn't be any more). So basically, this regex would return:
我需要得到最后一个破折号右边的文字。有时可能会有一个破折号,有时可能有两个破折号(不应再是破折号)。所以基本上,这个正则表达式会返回:
Package
Each
Solo Container
Tube
I'm always woefully ignorant when it comes to regex...
在正则表达方面,我总是很无知......
Edit: Per karthik manchala's suggestion...
编辑:按照karthik manchala的建议......
I tried the following:
我尝试了以下方法:
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.Pattern = "-\s*(\w+)"
strSearchString = _
"PK - Package"
strNewString = _
objRegEx.Replace(strSearchString, _
"")
MsgBox strNewString
and I'm getting the leftmost parts of the strings instead (PK, EA, etc...) Am I not using the replace correctly?
而我正在获取字符串最左边的部分(PK,EA等......)我没有正确使用替换?
Edit 2:
Played around a bit more and think I got it figure out. For anyone that may stumble upon this in the future, the following seems to have done the trick. Full code:
玩得更多,并认为我明白了。对于任何可能在将来偶然发现这一点的人来说,以下似乎已经成功了。完整代码:
Set objRegEx = _
CreateObject("VBScript.RegExp")
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.Pattern = "^[^-]*-* "
strSearchString = _
"PK - Package"
strNewString = _
objRegEx.Replace(strSearchString, _
"")
MsgBox strNewString
Message box shows "Package" even when there are 2 dashes.
即使有2个破折号,消息框也会显示“包”。
3 个解决方案
#1
- (.??)$
Matches from end to last dash
匹配从头到尾的破折号
Also this would work InstrRev
or StrReverse
and Instr
.
这也适用于InstrRev或StrReverse和Instr。
Do Until Inp.AtEndOfStream
A = Inp.Readline
Right(A, Len(A) - InstrRev(A, "-"))
Loop
#2
You can use the following:
您可以使用以下内容:
-\s*(\w+)
#3
This world would be a better place if
如果这个世界将是一个更好的地方
(1) People "woefully ignorant" wrt their problem would refrain from resticting the range of possible solutions by asking for specific techniques (RegExp and Replacing in this case) and concentrate on the specs: possible inputs, expected outputs/results. This can be done with skeleton code that tests possible solutions. E.g.:
(1)人们“非常无知”,他们的问题不会通过要求特定的技术(RegExp和在这种情况下更换)来重新排列可能的解决方案的范围,并专注于规范:可能的输入,预期的输出/结果。这可以通过测试可能解决方案的框架代码来完成。例如。:
Option Explicit
Function qq(s) : qq = """" & s & """" : End Function
Function getTail(sInp)
getTail = "????"
End Function
Dim aTests : aTests = Array( _
Split("PK - Package|Package", "|") _
, Split("AB - Solo Container|Solo Container", "|") _
)
Dim aTest
For Each aTest In aTests
Dim sInp : sInp = aTest(0)
Dim sExp : sExp = aTest(1)
Dim sAct : sAct = getTail(sInp)
WScript.Echo "----", qq(sInp)
If sAct = sExp Then
WScript.Echo "ok"
WScript.Echo " result:", qq(sAct)
Else
WScript.Echo "not ok"
WScript.Echo " got:", qq(sAct)
WScript.Echo "expected:", qq(sExp)
End If
Next
output:
cscript 30067065-1.vbs
---- "PK - Package"
not ok
got: "????"
expected: "Package"
---- "AB - Solo Container"
not ok
got: "????"
expected: "Solo Container"
(2) People wouldn't try to answer with untested code. Exploiting the fact that you can re-define a Sub/Function in VBScript, adding
(2)人们不会尝试用未经测试的代码回答。利用可以在VBScript中重新定义子/函数的事实,添加
' karthik, used as intended (Submatch), fails for "AB - Solo Container|Solo Container"
Function getTail(sInp)
Dim r : Set r = New RegExp
r.Pattern = "-\s*(\w+)"
Dim ms : Set ms = r.Execute(sInp)
If 1 = ms.Count Then
getTail = ms(0).SubMatches(0)
Else
getTail = "NOT: 1 = ms.Count"
End If
End Function
after the first version of getTail(), you get
在第一个版本的getTail()之后,你得到了
cscript 30067065-1.vbs
---- "PK - Package"
ok
result: "Package"
---- "AB - Solo Container"
not ok
got: "Solo"
expected: "Solo Container"
You can then easily test an improved pattern r.Pattern = "-\s*(.+)"
:
然后,您可以轻松地测试改进的模式r.Pattern =“ - \ s *(。+)”:
cscript 30067065-1.vbs
---- "PK - Package"
ok
result: "Package"
---- "AB - Solo Container"
ok
result: "Solo Container"
To see the flaw in Trigger's RegExp, you can add a further test case
要查看Trigger的RegExp中的缺陷,您可以添加进一步的测试用例
Dim aTests : aTests = Array( _
Split("PK - Package|Package", "|") _
, Split("AB - Solo Container|Solo Container", "|") _
, Split("Just For Trigger - X|X", "|") _
)
and a new version of getTail()
和新版本的getTail()
' Trigger, RegExp
Function getTail(sInp)
Dim r : Set r = New RegExp
r.Pattern = "- (.??)$"
Dim ms : Set ms = r.Execute(sInp)
If 1 = ms.Count Then
getTail = ms(0).SubMatches(0)
Else
getTail = "NOT: 1 = ms.Count"
End If
End Function
Result:
cscript 30067065-1.vbs
---- "PK - Package"
not ok
got: "NOT: 1 = ms.Count"
expected: "Package"
---- "AB - Solo Container"
not ok
got: "NOT: 1 = ms.Count"
expected: "Solo Container"
---- "Just For Trigger - X"
ok
result: "X"
"(.??)" looks for zero or one character different from \n non-greadily. I just hope that you didn't need test code to see that
“(。??)”寻找零或一个不同于\ n非greadily的字符。我只是希望你不需要测试代码来看
Right(A, Len(A) - InstrRev(A, "-"))
is not valid VBScript. Trigger's InStrRev technique could be used if improved further by Trim():
是无效的VBScript。如果Trim()进一步改进,可以使用触发器的InStrRev技术:
' Trigger, InStrRev improved
Function getTail(sInp)
getTail = Trim(Right(sInp, Len(sInp) - InstrRev(sInp, "-")))
End Function
Another non-RegExp approach uses Split():
另一种非RegExp方法使用Split():
' using Split
Function getTail(sInp)
Dim aTmp : aTmp = Split(sInp, "- ")
getTail = aTmp(UBound(aTmp))
End Function
(3) People would think twice before they upvote.
(3)人们在投票之前会三思而后行。
#1
- (.??)$
Matches from end to last dash
匹配从头到尾的破折号
Also this would work InstrRev
or StrReverse
and Instr
.
这也适用于InstrRev或StrReverse和Instr。
Do Until Inp.AtEndOfStream
A = Inp.Readline
Right(A, Len(A) - InstrRev(A, "-"))
Loop
#2
You can use the following:
您可以使用以下内容:
-\s*(\w+)
#3
This world would be a better place if
如果这个世界将是一个更好的地方
(1) People "woefully ignorant" wrt their problem would refrain from resticting the range of possible solutions by asking for specific techniques (RegExp and Replacing in this case) and concentrate on the specs: possible inputs, expected outputs/results. This can be done with skeleton code that tests possible solutions. E.g.:
(1)人们“非常无知”,他们的问题不会通过要求特定的技术(RegExp和在这种情况下更换)来重新排列可能的解决方案的范围,并专注于规范:可能的输入,预期的输出/结果。这可以通过测试可能解决方案的框架代码来完成。例如。:
Option Explicit
Function qq(s) : qq = """" & s & """" : End Function
Function getTail(sInp)
getTail = "????"
End Function
Dim aTests : aTests = Array( _
Split("PK - Package|Package", "|") _
, Split("AB - Solo Container|Solo Container", "|") _
)
Dim aTest
For Each aTest In aTests
Dim sInp : sInp = aTest(0)
Dim sExp : sExp = aTest(1)
Dim sAct : sAct = getTail(sInp)
WScript.Echo "----", qq(sInp)
If sAct = sExp Then
WScript.Echo "ok"
WScript.Echo " result:", qq(sAct)
Else
WScript.Echo "not ok"
WScript.Echo " got:", qq(sAct)
WScript.Echo "expected:", qq(sExp)
End If
Next
output:
cscript 30067065-1.vbs
---- "PK - Package"
not ok
got: "????"
expected: "Package"
---- "AB - Solo Container"
not ok
got: "????"
expected: "Solo Container"
(2) People wouldn't try to answer with untested code. Exploiting the fact that you can re-define a Sub/Function in VBScript, adding
(2)人们不会尝试用未经测试的代码回答。利用可以在VBScript中重新定义子/函数的事实,添加
' karthik, used as intended (Submatch), fails for "AB - Solo Container|Solo Container"
Function getTail(sInp)
Dim r : Set r = New RegExp
r.Pattern = "-\s*(\w+)"
Dim ms : Set ms = r.Execute(sInp)
If 1 = ms.Count Then
getTail = ms(0).SubMatches(0)
Else
getTail = "NOT: 1 = ms.Count"
End If
End Function
after the first version of getTail(), you get
在第一个版本的getTail()之后,你得到了
cscript 30067065-1.vbs
---- "PK - Package"
ok
result: "Package"
---- "AB - Solo Container"
not ok
got: "Solo"
expected: "Solo Container"
You can then easily test an improved pattern r.Pattern = "-\s*(.+)"
:
然后,您可以轻松地测试改进的模式r.Pattern =“ - \ s *(。+)”:
cscript 30067065-1.vbs
---- "PK - Package"
ok
result: "Package"
---- "AB - Solo Container"
ok
result: "Solo Container"
To see the flaw in Trigger's RegExp, you can add a further test case
要查看Trigger的RegExp中的缺陷,您可以添加进一步的测试用例
Dim aTests : aTests = Array( _
Split("PK - Package|Package", "|") _
, Split("AB - Solo Container|Solo Container", "|") _
, Split("Just For Trigger - X|X", "|") _
)
and a new version of getTail()
和新版本的getTail()
' Trigger, RegExp
Function getTail(sInp)
Dim r : Set r = New RegExp
r.Pattern = "- (.??)$"
Dim ms : Set ms = r.Execute(sInp)
If 1 = ms.Count Then
getTail = ms(0).SubMatches(0)
Else
getTail = "NOT: 1 = ms.Count"
End If
End Function
Result:
cscript 30067065-1.vbs
---- "PK - Package"
not ok
got: "NOT: 1 = ms.Count"
expected: "Package"
---- "AB - Solo Container"
not ok
got: "NOT: 1 = ms.Count"
expected: "Solo Container"
---- "Just For Trigger - X"
ok
result: "X"
"(.??)" looks for zero or one character different from \n non-greadily. I just hope that you didn't need test code to see that
“(。??)”寻找零或一个不同于\ n非greadily的字符。我只是希望你不需要测试代码来看
Right(A, Len(A) - InstrRev(A, "-"))
is not valid VBScript. Trigger's InStrRev technique could be used if improved further by Trim():
是无效的VBScript。如果Trim()进一步改进,可以使用触发器的InStrRev技术:
' Trigger, InStrRev improved
Function getTail(sInp)
getTail = Trim(Right(sInp, Len(sInp) - InstrRev(sInp, "-")))
End Function
Another non-RegExp approach uses Split():
另一种非RegExp方法使用Split():
' using Split
Function getTail(sInp)
Dim aTmp : aTmp = Split(sInp, "- ")
getTail = aTmp(UBound(aTmp))
End Function
(3) People would think twice before they upvote.
(3)人们在投票之前会三思而后行。