i need your help.
in vbscript i have a string such as
s = 'Abc' and 'Def' Or 'Ghin' In 'jkl' not 'mnoR' And ... or ... NOT ... iN ...
and i want to uppercase these specific 4 operators (in any combination of lower and upper text): and, or, in, not, to Uppercase.
These operators exist outside the quotes (') - because between them i have business rules. This is important, because, as you can see in 3rd rule ('Ghin') i have 'in' in the name of the rule and in these cases i do not want the text between the quotes (business rule name) to be altered.
How can i solve this in vbscript, preferently using RegEx?
TIA
EDIT:
Thanks for your help.
Sorry, but i forgot to mention one detail: i can have text outside the quotes, namely "(" , ")", "[","]" or conditions as "1 = 1", but again: the operators to be changed exist outside the quotes and inside quotes nothing is done.
Using the previous example:
s = "('abc' and ['Def' Or 'Ghin'] In 'jkl' not 1=1 AND 'mnoR' And 'pqr' or 'xyz' NOT 'lmn' iN 'Opq')"
s = "('abc' AND ['Def' OR 'Ghin'] IN 'jkl' NOT 1=1 AND 'mnoR' AND 'pqr' OR 'xyz' NOT 'lmn' IN 'Opq')"
In other languages you may use a fancy look around pattern to (logically) apply a regexp to parts of your input only, in VBScript you should use either a regexp replace function with a state or Split().
Demo script for the first alternative:
Dim gb_magic : gb_magic = True
Function gf_magic(sMatch, nPos, sSrc)
gf_magic = sMatch
If "'" = sMatch Then
gb_magic = Not gb_magic
Else
If gb_magic Then
gf_magic = UCase(sMatch)
End If
End If
End Function
Dim s : s = "s = 'Abc and def' and 'not Def' Or 'Ghin' In 'jkl in or' not 'mnoR'"
WScript.Echo s
Dim r : Set r = New RegExp
r.Global = True
r.IgnoreCase = True
r.Pattern = "and|not|or|in|'"
gb_magic = True
s = r.Replace(s, GetRef("gf_magic"))
WScript.Echo s
output:
s = 'Abc and def' and 'not Def' Or 'Ghin' In 'jkl in or' not 'mnoR'
s = 'Abc and def' AND 'not Def' OR 'Ghin' IN 'jkl in or' NOT 'mnoR'
Keeping the method exposed by Ekkehard solution, but translating the state variable into the regular expression.
It has the drawback of a string concatenation inside the function, but it only gets called for the found operators and not for the quotes.
Dim originalString
originalString = "not 'Abc and def' and 'not Def' Or 'Ghin' In 'jkl in or' not 'mnoR' and"
Dim convertedString
Function correctCase(matchString,leftPart,operator,rightPart,position,sourceString)
correctCase = leftPart & UCase(operator) & rightPart
End Function
With New RegExp
.Pattern = "((?:'[^']*'){0,}\s*)(and|or|not|in)((?:\s*'[^']*'){0,})"
.Global = True
.IgnoreCase = True
convertedString = .Replace(originalString,GetRef("correctCase"))
End With
WScript.Echo originalString
WScript.Echo convertedString
Something like this should work
Dim s
s = "'abc' and 'Def' Or 'Ghin' In 'jkl' not 'mnoR' And 'pqr' or 'xyz' NOT 'lmn' iN 'asd'"
s = RegExReplace(s,"\band\b","AND")
s = RegExReplace(s,"\bor\b","OR")
s = RegExReplace(s,"\bnot\b","NOT")
s = RegExReplace(s,"\bin\b","IN")
msgbox s
Function RegExReplace(OriginalStr, RegExPattern, NewStr)
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.Pattern = RegExPattern
RegExReplace=objRegEx.Replace(OriginalStr, NewStr)
End Function
Using regular expressions is a must?
s = "('abc' and ['Def' Or 'Ghin'] In 'jkl' not 1=1 AND 'mnoR' And 'pqr' or 'xyz' NOT 'lmn' iN 'Opq')"
p = split(s, "'")
for i = 0 to ubound(p) step 2
p(i) = ucase(p(i))
next
r = join(p, "'")
msgbox r
I would agree a regex solution is the way to go. But it seems to me that you could just search for your keywords surrounded by spaces, unless of course your business rules include that type of pattern as well.
For Each k In Array(" AND ", " OR ", " IN ", " NOT ")
s = Replace(s, k, k, 1, -1, vbTextCompare)
Next
This will find your keywords (on their own, not contained within another word) and replace any instances with uppercase versions.