advanced replace - add character to paragraph

N

nico

Hi,

I'm trying to migrate wikis, and thought Word's Replace might be good (and
it is, generally). Want I can't get to work is to make sure that every
paragraph that ends in ** should also start with ** (they should be added),
while every paragraph that starts with ** should also end with it. Some
paragraphs will have two stars both at the beginning and at the end already,
while some have it only at the beginning and some only at the end. I don't
want to end up with four stars in any place. What's the quickest way to do
that? I had tried searching for ^13(\*\*)(*)([!^13])([!\*\*])(^13^13) and
replacing this with ^p**\2**^p^p**
but it didn't work as expected.

Thanks for any help!
Nico
 
H

Helmut Weber

Hi Nico,

to me, wildcard searches are too complicated.

Sub Test40X()
Dim oPrg As Paragraph
For Each oPrg In ActiveDocument.Paragraphs
With oPrg.Range
If Len(.Text) <> 1 Then
While .Characters.First = "*"
.Characters.First = ""
Wend
While .Characters.Last.Previous = "*"
.Characters.Last.Previous = ""
Wend
.Characters.First = "**"
.Characters.Last.Previous = "**"
End If
End With
Next
End Sub

Should be fast enough.
There is still room for improvement.
The macro skips empty paragraphs and
processes the first paragraph, as well,
which is always a problem with wildcards,
when using chr(13) & something.

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
K

Karl E. Peterson

Helmut Weber said:
Hi Nico,

to me, wildcard searches are too complicated.

Yeah, I hear that.
Sub Test40X()
Dim oPrg As Paragraph
For Each oPrg In ActiveDocument.Paragraphs
With oPrg.Range
If Len(.Text) <> 1 Then
While .Characters.First = "*"
.Characters.First = ""
Wend
While .Characters.Last.Previous = "*"
.Characters.Last.Previous = ""
Wend
.Characters.First = "**"
.Characters.Last.Previous = "**"
End If
End With
Next
End Sub

Here's another approach that doesn't lean so heavily on the object model:

Sub Test40X()
Dim oPrg As Paragraph
Dim txt As String
For Each oPrg In ActiveDocument.Paragraphs
txt = oPrg.Range.Text
If Len(txt) >= 2 Then
Select Case True
Case (Left$(txt, 2) = "**") And (Right$(txt, 2) = "**")
' do nothing
Case (Left$(txt, 2) = "**")
txt = txt & "**"
Case (Right$(txt, 2) = "**")
txt = "**" & txt
Case Else
' do nothing
End Select
End If
oPrg.Range.Text = txt
Next
End Sub
 
H

Helmut Weber

Hi Karl,
Yeah, I hear that.

Not always, but it needs a special talent.
So to speak, some like to twist their brain.

Results in an endless loop here and now.

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
H

Helmut Weber

Hi Karl,

it's very late here, not to say early in the morning.

It's your code, that loops endlessly, not mine. :)

Maybe something went wrong with your code when copying and pasting.

Cheers

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
N

nico

Sorry, can't get this one to work. It adds stars to all paragraphs, rather
than just to the ones that have ** either in front or at the back (but not
both). It also 'swallows' the last character of the text. I've tried for some
time to find a way to insert characters, or to change the code so that it
would ignore starless paragraphs, but have had no success.

Thanks anyway, I did learn more about VB.
 
N

nico

Hi Karl,

Also couldn't get this one to work. For some reason the oPrg.Range.Text =
txt prevents the NEXT loop from working properly, resulting in an endless
loop. Otherwise it would seem that this is as close as it gets.
Cheers.
 
K

Karl E. Peterson

Helmut Weber said:
Hi Karl,

it's very late here, not to say early in the morning.

It's your code, that loops endlessly, not mine. :)

Maybe something went wrong with your code when copying and pasting.

Well, it was AirCode<tm>, sorry for not posting a warning. I just took your loop,
and redid the guts. <g>
 
K

Karl E. Peterson

nico said:
Also couldn't get this one to work. For some reason the oPrg.Range.Text =
txt prevents the NEXT loop from working properly, resulting in an endless
loop. Otherwise it would seem that this is as close as it gets.

Dang! You don't know how often I get away with posting AirCode, either. I'm sorry,
but I have no idea why that might be, and as things stand I'm late for supper! If
this remains unsolved tommorow, I'll take another look at it.

Good luck!
 
D

Doug Robbins - Word MVP

The following code will do all but put the ** before the first paragraph in
the document:

Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find
Do While .Execute(findText:="[!\*]{2}^13", ReplaceWIth:="**^p",
MatchWildcards:=True, Forward:=True, Wrap:=wdFindStop) = True
Loop
End With
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find
Do While .Execute(findText:="^13[!\*]{2}", ReplaceWIth:="^p**",
MatchWildcards:=True, Forward:=True, Wrap:=wdFindStop) = True
Loop
End With


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP
 
H

Helmut Weber

Hi Nico,

my solution was alright, but not for your problem. :-( ;-)

I didn't read the question correctly.


On my and I dare say an Karl's behalf, too.
This is what we had in mind.

Sub Test40XX()
Dim p As Paragraph
Dim s As String ' a string
Dim c As Long ' a case
Dim r As Range ' a range
For Each p In ActiveDocument.Range.Paragraphs
With p.Range
Set r = p.Range
r.End = r.End - 1
r.Select
s = r.Text
If Left(s, 2) <> "**" And Right(s, 2) <> "**" Then c = 1
If s = "" Then c = 0 ' do nothing
If Right(s, 2) = "**" Then c = 2
If Left(s, 2) = "**" Then c = 3
If Left(s, 2) = "**" And Right(s, 2) = "**" Then c = 0 ' do
nothing
Select Case c
Case 1: s = "**" & s & "**"
Case 2: s = "**" & s
Case 3: s = s & "**"
End Select
r.Text = s
End With
Next
End Sub

I excluded the paragraph mark from overwriting,
as it may lose formatting by the above method.
 
K

Klaus Linke

To add missing asterisks at the end of paragraphs (that have two at the
start):

Find what: (^13\*\*[!^13]@[!\*][!\*])(^13)
Replace with: \1**\2

To add missing asterisks at the start of paragraphs (that have two at the
end):
Find what: (^13)([!\*][!\*][!^13]@\*\*^13)
Again, Replace with: \1**\2

According to Helmut, I must have a twist in my brain...
<g> Klaus
 
K

Klaus Linke

Ouch... You'll have to do the replacements twice.

That's a common problem when you want to want to match both for the start
and the end of the paragraph.
Because Word widcards have no anchors for the start and end of paragraphs
(like the "<" and ">" anchors for the beginning and end of words), you have
to match the paragraph mark of the preceeding paragraph. That way, you match
more than one paragraph, and will likely miss some.
A second run of the wildcard replacement will fix that though, and those 4
replacements will still likely be faster than looping paragraphs.

Anchors for the beginning and end of paragraphs would be very nice to
have... especially considering that users don't even easily discover the
possible use of ^13 for ^p.

Klaus
 
H

Helmut Weber

Hi Klaus,
According to Helmut, I must have a twist in my brain...

sure, one might call it a special talent as well. :)
You may have fun with Excel-formulae,
which I am hopeless with.

My last code incloses all paragraphs
that have neither leading nor trailing double asteriscs,
in asteriscs, too. Still didn't get the question.

I'll be off for playing chess. It's clear and simple.

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
N

nico

I won't be able to test and report the results for a while, but be sure that
I will come back after Easter. All the best for your holidays, too, and
thousand thanks for your help!!
 
K

Klaus Linke

Happy holidays!

Klaus


nico said:
I won't be able to test and report the results for a while, but be sure
that
I will come back after Easter. All the best for your holidays, too, and
thousand thanks for your help!!
 
R

Russ

Find what: (^13\*\*[!^13]@[!\*][!\*])(^13)
Replace with: \1**\2

To add missing asterisks at the start of paragraphs (that have two at the
end):
Find what: (^13)([!\*][!\*][!^13]@\*\*^13)
Again, Replace with: \1**\2
Hi,

I'm trying to migrate wikis, and thought Word's Replace might be good (and
it is, generally). Want I can't get to work is to make sure that every
paragraph that ends in ** should also start with ** (they should be
added),
while every paragraph that starts with ** should also end with it. Some
paragraphs will have two stars both at the beginning and at the end
already,
while some have it only at the beginning and some only at the end. I don't
want to end up with four stars in any place. What's the quickest way to do
that? I had tried searching for ^13(\*\*)(*)([!^13])([!\*\*])(^13^13) and
replacing this with ^p**\2**^p^p**
but it didn't work as expected.

Thanks for any help!
Nico

Ouch... You'll have to do the replacements twice.

That's a common problem when you want to want to match both for the start
and the end of the paragraph.
Because Word widcards have no anchors for the start and end of paragraphs
(like the "<" and ">" anchors for the beginning and end of words), you have
to match the paragraph mark of the preceeding paragraph. That way, you match
more than one paragraph, and will likely miss some.
A second run of the wildcard replacement will fix that though, and those 4
replacements will still likely be faster than looping paragraphs.

I agree on the speed issue.
However, if there is no paragraph mark at the beginning of the document, the
first 'non-empty' paragraph will not be tested. But you could temporarily
add a paragraph mark before running the "Finds and Replaces" and delete the
temporary mark afterwards.

ActiveDocument.Range.InsertBefore vbCr
' Do Finds and Replaces
ActiveDocument.Characters(1).Delete
Anchors for the beginning and end of paragraphs would be very nice to
have... especially considering that users don't even easily discover the
possible use of ^13 for ^p.

I agree. I would hope that Microsoft would employ smarter Regular
Expressions in a future version of Word.
Referenced, newer Regular Expressions VBA code modules might even be used
in older versions of Word, if they were referenced via VBA code.

MacWord people should use \n or [\^13] instead of just ^13 in their
paragraph mark "Finds".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top