Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Replace routine
#1
Have you guys noticed that "wrap" on searches like Notepad only work when a line-break in not encountered? That makes sense, I guess, but what if you wanted to ignore those line-breaks and find what you are looking for, anyway?

Pete is
tremendous but
Steve is just amazing.

So search that for Pete is tremendous. No go in most html editors or Notepad. I don't Word or OpenOffice, anymore, so I don't know if they would find the search or not.

Anyway, I got a little burned out with trying a strict math model to accomplish this, so I combined a math and string replacement method to get the job done. It's super fast, but it has a drawback in that the file being searched cannot contain 3 substitute string characters I used to handle the line-break situation. Chr$(1), Chr$(3), and Chr$(4). Us SCREEN 0 card programmers are screwed for diamonds and hearts!

So I'm curious if anyone has coded this and figured out a pure math method? 

Now the routine itself is actually very useful for html files, which often contain text broken up on different lines. I coded it to preserve line-breaks. I have not, and may not go to the extent of perfect line-break mirroring, as that would require checking the for the nearest space in the replacement term instead of stacking the line-breaks onto the end. Yes, it can handle search and replace over multiple line-breaks. For instance...

Pete is
tremendous but

Steve is just amazing.

Search for: Pete is tremendous
Replace with: Pete is TREMENDOUS

The results with my routine would be...

Pete is TREMENDOUS

but
Steve is just amazing.

instead of...

Pete is
TREMENDOUS but

Steve is just amazing.
----------------------------------------
So not an exact mirror, but it does get the job, essentially, done.

Here's the code. It won't change any of your files, or make any new ones. It just loads the edited content to your clipboard and opens Notepad. You can paste it in to view it. Just pick a text file (.bas, .txt, .html, etc.), or make a test file, to try it out.

Code: (Select All)
Width 80, 25: _Font 16: _ScreenMove _Middle
Print "Opening file dialog..."
target$ = _OpenFileDialog$("Open a file to to be searched:", "", "*.*", "", 0)
If target$ = "" Then System
Print: Print "This routine copies the contents of the file to your clipboard.": Print
search:
If _FileExists(target$) Then Else Print "Error, file not found: " + target$: End
Dim As Integer seed, q, j, k, i1, i3, i4
Open target$ For Binary As #1
a$ = Space$(LOF(1))
Get #1, , a$
Close #1
Line Input "Search for:  ", find$: Print
Line Input "Replace with: ", replace$: Print
If find$ <> replace$ Then
    a2$ = a$: c = 0
    Do ' Strip out line-breaks and substitute space for a single line-break.
        q = InStr(seed, a$, Chr$(13) + Chr$(10))
        If q Then
            If Mid$(a$, q + 2, 2) = Chr$(13) + Chr$(10) Or Mid$(a$, q + 2) = "" Then
                sp$ = "": sp2$ = ""
                For j = 0 To Len(a2$) Step 2
                    If Mid$(a2$, q + j, 2) <> Chr$(13) + Chr$(10) Then Exit For
                Next
                If j Then lb = lb + 1: ReDim _Preserve line_break(lb) As Integer: line_break(lb) = j / 2
            Else
                sp$ = " ": sp2$ = Chr$(1): If j Then sp2$ = Chr$(3)
                j = 0
            End If
            a$ = Mid$(a$, 1, q - 1) + sp$ + Mid$(a$, q + 2)
            a2$ = Mid$(a2$, 1, q - 1) + sp2$ + Mid$(a2$, q + 2)
            seed = q
        Else
            Exit Do
        End If
        c = c + 1: If c > 1000 Then Print "Oops. We went over 1000 loops without completing the routine.": End ' For beta version this prevents an endless loop for any unhandled condition.
    Loop
    seed = 1
    Do ' Find and Replace.
        q = InStr(seed, LCase$(a$), LCase$(find$))
        If q And Len(find$) <> 0 Then
            Mid$(a2$, q, 1) = Chr$(4)
            seed = q + Len(find$)
        Else
            Exit Do
        End If
    Loop
    j = 0: a$ = "" ' Reconstruct.
    Do
        i1 = InStr(a2$, Chr$(1))
        i3 = InStr(a2$, Chr$(3))
        i4 = InStr(a2$, Chr$(4))
        While -1
            If i1 Then
                If i1 < i3 Or i3 = 0 Then
                    If i1 < i4 Or i4 = 0 Then
                        q = i1
                        x$ = Chr$(13) + Chr$(10)
                        GoSub assemble
                        Exit While
                    End If
                End If
            End If
            If i3 Then
                If i3 < i1 Or i1 = 0 Then
                    If i3 < i4 Or i4 = 0 Then
                        q = i3
                        j = j + 1: x$ = ""
                        For k = 1 To line_break(j): x$ = x$ + Chr$(13) + Chr$(10): Next
                        GoSub assemble
                        Exit While
                    End If
                End If
            End If
            If i4 Then
                If i4 < i1 Or i1 = 0 Then
                    If i4 < i3 Or i3 = 0 Then
                        x$ = replace$
                        q = i4
                        GoSub assemble
                        x$ = Mid$(a2$, 1, Len(find$))
                        For i = 1 To Len(find$)
                            Select Case Mid$(a2$, i, 1)
                                Case Chr$(1)
                                    lb$ = Chr$(13) + Chr$(10)
                                Case Chr$(3)
                                    j = j + 1: x$ = ""
                                    For k = 1 To line_break(j): lb$ = lb$ + Chr$(13) + Chr$(10): Next
                            End Select
                        Next
                        a$ = a$ + lb$: lb$ = ""
                        q = Len(find$)
                        If Mid$(a2$, q, 1) = " " And Right$(a$, 2) = Chr$(13) + Chr$(10) Then q = q + 1 ' Remove leading space.
                        a2$ = Mid$(a2$, q)
                        Exit While
                    End If
                End If
            End If
            a$ = a$ + a2$: a2$ = "": Exit Do ' End of file.
            Exit While
        Wend
    Loop
End If
Print "Finished. Do a Notepad paste to view results. (Opening Notepad...)": Print
Print: Print "[Enter] Run  [Tab] Search this file again.  [Esc] Quit"
Shell _DontWait _Hide "start notepad"
_Clipboard$ = a$
Sleep
Select Case InKey$
    Case Chr$(13): Cls: _Delay .5: Run
    Case Chr$(27): System
    Case Chr$(9): Cls: GoTo search
End Select
System

assemble:
a$ = a$ + Mid$(a2$, 1, q - 1) + x$
a2$ = Mid$(a2$, q + 1)
Return

Basically I'm just curious about my approach, different approaches, and use. If you can think of another use, different output, or different build approach, I'd enjoy reading the comments and engaging in the conversation.

Pete
Reply


Messages In This Thread
Replace routine - by Pete - 10-31-2024, 12:11 AM
RE: Replace routine - by Kernelpanic - 10-31-2024, 01:06 PM
RE: Replace routine - by bplus - 10-31-2024, 01:16 PM
RE: Replace routine - by Pete - 10-31-2024, 04:46 PM



Users browsing this thread: 2 Guest(s)