[removed] how to Uppercase specific parts of text

2019-07-26 13:37发布

问题:

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')"

回答1:

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'


回答2:

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


回答3:

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


回答4:

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


回答5:

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.