Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Use VBS RegExp to replace a-z with A-Z?

16 views
Skip to first unread message

Tushar Mehta

unread,
Aug 4, 2002, 9:56:15 AM8/4/02
to
Is there a way to use the VBS RegExp object (and its Replace method) to
replace the first instance of a letter after a period with the
uppercased version of the letter?

Something like replace \.( )*[a-z] with \.(<same number of spaces>)[A-
Z]?

Also, in the msdn documentation on the replace method
(http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/script56/html/vsmthreplace.asp), the last example, which is
MsgBox(ReplaceText("(\S+)(\s+)(\S+)", "$3$2$1")) ' Swap pairs of
words.
uses $3$2$1. Where would I learn more on the $<number> piece?

--
Regards,

Tushar Mehta
www.tushar-mehta.com
Microsoft MVP -- Excel
--

Daniel.M

unread,
Aug 4, 2002, 12:38:01 PM8/4/02
to
Hi Tushar,

> Is there a way to use the VBS RegExp object to replace the first ...
Yes

>(and its Replace method) to replace the first ...
Not that I know of.

AFAIK, since you're changing a submatch (capitalizing-it), you need a
special UDF to do what you want.

MatchGrep() is a function I wrote the returns the SUBMATCHES of the first
match (important) in an array. The item 0 of the array is the number of
SUBMATCHES. Subsequent items are the submatches themselves.
' MatchGrep()
' January 2002 Daniel Maher
' Populates an 1D array (so horizontal if used in a SS)
' with item 0 = Number of submatches
' item 1 to n = The submatches themselves
Public Function MatchGrep(ByVal Texte As String, ByVal Pat As String, _
Optional CaseSensitive As Boolean = False) As Variant

Dim REE As RegExp, MC As MatchCollection, i%
Dim aRes As Variant ' Array of results

If Texte = "" Or Pat = "" Then ' Non-valid args
ReDim aRes(0 To 0)
aRes(0) = 0
MatchGrep = aRes
Exit Function
End If

Set REE = New RegExp
REE.Pattern = Pat
REE.Global = False
REE.IgnoreCase = Not CaseSensitive
Set MC = REE.Execute(Texte)

If MC.Count = 0 Then ' No match
ReDim aRes(0 To 0)
aRes(0) = 0
MatchGrep = aRes
Else ' only for the first match
With MC(0).SubMatches
ReDim aRes(0 To .Count)
aRes(0) = .Count
For i = 1 To .Count
' Associate submatches to results
aRes(i) = .Item(i - 1)
Next i
MatchGrep = aRes
End With
End If
Set MC = Nothing: Set REE = Nothing 'Cleanup
End Function


Then, a function like the following would suit your needs (I think) :

Function foo(s$)
Dim v As Variant
v = MatchGrep(s, "\.( *)([a-z])")
foo = "." & v(1) & UCase(v(2))
End Function


> Also, in the msdn documentation on the replace method
> (http://msdn.microsoft.com/library/default.asp?url=/library/en-
> us/script56/html/vsmthreplace.asp), the last example, which is
> MsgBox(ReplaceText("(\S+)(\s+)(\S+)", "$3$2$1")) ' Swap pairs of
> words.
> uses $3$2$1. Where would I learn more on the $<number> piece?

AFAIK, Perl docs cover these aspects (replacing with subgroups).
FYI, Harlan Grove has written very slick and useful grep-like substitutions
functions involving RegExp object (I think most of them operate on the match
collection, not the submatch items of one match).

Regards,

Daniel M.


Tushar Mehta

unread,
Aug 4, 2002, 6:46:24 PM8/4/02
to
Thanks for your comments. I wrote a similar UDF. The initial
development relied on a reference to VBScript Regular Expressions.
However, in the final version, I went with late binding. Hopefully,
that means the code will work with whatever version is on the computer.

Option Explicit

Function CapFirstLetterOfSentences(ByVal Str As String) As String
Dim aRegExp As Object, aMatch As Object, allMatches As Object
Set aRegExp = CreateObject("vbscript.regexp")
aRegExp.Pattern = "^[a-z]|\.( )*[a-z]"
aRegExp.Global = True
Set allMatches = aRegExp.Execute(Str)
For Each aMatch In allMatches
With aMatch
Mid(Str, .firstindex + 1 + .Length - 1, 1) = _
UCase(Mid(Str, .firstindex + 1 + .Length - 1, 1))
End With
Next aMatch
CapFirstLetterOfSentences = Str
End Function
Sub testIt()
Dim Str As String
Str = "this is the 1ST sentence. second sentence. This " _
& "requires no caps.a sentence with no leading spaces." _
& " sentence with 10 leading spaces"
MsgBox Str & vbNewLine & CapFirstLetterOfSentences(Str)
End Sub


--
Regards,

Tushar Mehta
www.tushar-mehta.com
Microsoft MVP -- Excel
--

In <ujlWAT9OCHA.444@tkmsftngp12>, Daniel.M <daniel...@bigfoot.com>
wrote

Daniel.M

unread,
Aug 5, 2002, 11:18:14 AM8/5/02
to
Hi Tushar,

Too bad that a transformation of specific parts of a regexp can't be done
via a generic Replace statement. We have to build specific UDF (and I see
you build yours!).

BTW, my definition of a sentence differ from yours (expressed in your
.Pattern). If there are spaces before your 1st stentence (and paragraph
beginnings are often like this), it won't be capitalized.
You can certainly disagree but I would use something like (still with late
binding) :

Function CapFirstLetterOfSentences(ByVal Str As String) As String
Dim aRegExp As Object, aMatch As Object, allMatches As Object
Set aRegExp = CreateObject("vbscript.regexp")

aRegExp.Pattern = "(\s*)(\w)([^.?!]*)([.?!]+)"


aRegExp.Global = True
Set allMatches = aRegExp.Execute(Str)

Str = ""


For Each aMatch In allMatches

With aMatch.SubMatches
Str = Str & .Item(0) & UCase(.Item(1)) & .Item(2) & .Item(3)


End With
Next aMatch
CapFirstLetterOfSentences = Str
End Function

Sub testIt()
Dim Str As String

Str = " this is the 1ST sentence... second sentence!! This " _
& "requires no caps!a sentence with no leading spaces?!" _
& " sentence with 10 leading spaces!?"


MsgBox Str & vbNewLine & CapFirstLetterOfSentences(Str)
End Sub

You'll notice every sentence must be completed (ended with a . / ? / !) to
be processed.

Have a nice day,

Daniel M.

"Tushar Mehta" <ng_p...@bigfoot.com> wrote in message
news:MPG.17b778cac...@msnews.microsoft.com...

0 new messages