Announcement

Collapse
No announcement yet.

RegRepl Question

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • RegRepl Question

    I've having trouble using RegRepl with what I'd think was a simple problem.

    I'd like to replace all single occurrences of $CRLF with a $Spc but retain all multiple occurrences of $CRLF.

    For example,

    Code:
    "abc" + $crlf + "def" + $crlf + $crlf + "ghi" + $crlf + "jkl"
    becomes
    "abc def" + $crlf + $crlf + "ghi jkl"
    I assume I start with this, but from the Help page I can't interpret how to modify the RegRepl mask$ to skip multiple occurrences of $CRLF.

    Code:
    Function PBMain() As Long
       Local a$,b$, iPos As Long
       a$ = "abc" + $CrLf + "def" + $CrLf + $CrLf + "ghi" + $CrLf + "jkl"
       Do
          RegRepl $CrLf In a$ With $Spc To iPos, a$
       Loop While iPos
       ? a$
    End Function
    Can someone guide me here?


  • #2
    I can do it with REPLACE, like this ...

    Code:
    Function PBMain() As Long
       Local a$,b$, iPos As Long
       a$ = "abc" + $CrLf + "def" + $CrLf + $CrLf + "ghi" + $CrLf + "jkl"
       Replace  $CrLf + $CrLf With Chr$(0) In a$
       Replace $CrLf With $Spc In a$
       Replace Chr$(0) With $CrLf In a$
       ? a$
    End Function
    But this fails if there are more than 2 occurrences of $CRLF in a row. I could add extra lines for 3, 4, or more $CRLFs in a row, but I thought a RegRepl might be a better solution.

    Comment


    • #3
      Here's the REPLACE approach, taking into account up to 4 $CRLF in sequence. I could use a loop to extend it to any number of $CRLF, but I'd think the more minimal (if not slower?) approach would be using RegRepl.

      Code:
      Function PBMain() As Long
         Local a$,b$, iPos As Long
         a$ = "abc" + $CrLf + "def" + $CrLf + $CrLf + "ghi" + $CrLf + "jkl"
         Replace  $CrLf + $CrLf + $CrLf + $CrLf With Chr$(0) In a$
         Replace  $CrLf + $CrLf + $CrLf With Chr$(0) In a$
         Replace  $CrLf + $CrLf With Chr$(0) In a$
         Replace $CrLf With $Spc In a$
         a$ = Shrink$(a$,Chr$(0)+Chr$(0))
         Replace Chr$(0) With $CrLf + $CrLf In a$
         ? a$
      End Function

      Comment


      • #4
        Code:
        Replace  $CRLF + $CRLF With $NUL In a$
        WHILE INSTR(a$, $NUL+$CRLF)
            Replace $NUL+$CRLF  With $NUL+$NUL In a$
        WEND
        Added: I see that you already considered a loop but I had already typed this.
        "Not my circus, not my monkeys."

        Comment


        • #5
          Well, this is embarrassing! I found a solution in my gbSnippets library. I've forgotten I'd ever solved it and I didn't use the right snippets search term to find the prior work!

          Code:
          Function PBMain() As Long
             Local temp$, iPos As Long
             temp$ = "abc" + $CrLf + "def" + $CrLf + $CrLf + "ghi" + $CrLf + "jkl"
             Do
                Incr iPos
                RegRepl "(\r\n)" In temp$ With $Spc At iPos To iPos, temp$
             Loop While iPos
             ? temp$
          End Function

          Comment


          • #6
            Code:
            replace $lf & $cr   with $nul      in a$
            replace $crlf       with $spc      in a$
            replace $nul        with $lf & $cr in a$

            Comment


            • #7
              Well, Pierre,
              That's an interesting approach.

              It works on even numbers of $CRLF strings, but for odd numbers of $CRLFs in the string, there will be a floating $LF.

              Comment


              • #8
                Bummer, the approach I said worked (#5) doesn't handle 3 $CRLFs correctly either.

                The more cumbersome approach I posted in #3 does seem to cover 2+ $CRLFs.

                Comment


                • #9
                  Little correction done, try it again...

                  Comment


                  • #10
                    Yep, Pierre, better. I don't lose my multiple CRLFs and it's only half as many steps as I took up in #3.

                    I'm loading some fairly large books (5-10MB) into a RichEdit for viewing. If I do that realtime, speed matters. But I'll probably make a bulk conversion of the books ahead of time just to avoid the load/convert delay time.

                    Comment


                    • #11
                      Found this in a drawer - old code used for rplacing single line feeds with a space in text, but keeping all "grouped" ones as-is. Useful? At least pretty fast and if I understand the task correctly, it should work for your purpose.
                      Edited - yeah, I know I say Remove, but I mean Replace with a space...
                      Code:
                      #COMPILE EXE
                      #INCLUDE "WIN32API.INC"
                      
                      '====================================================================
                      FUNCTION PBMAIN () AS LONG
                        LOCAL hDlg AS DWORD
                      
                        DIALOG NEW 0, "Replace Single Line Feeds with Space",,, 220, 140, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg
                      
                        CONTROL ADD BUTTON, hDlg, %IDOK,     "&Action", 112, 122, 50, 14
                        CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Quit",   166, 122, 50, 14
                      
                        DIALOG SHOW MODAL hDlg CALL DlgProc
                      
                      END FUNCTION
                      
                      
                      '====================================================================
                      CALLBACK FUNCTION DlgProc() AS LONG
                        LOCAL sTmp AS STRING, t AS DOUBLE
                      
                        SELECT CASE AS LONG CB.MSG
                        CASE %WM_INITDIALOG
                      
                        CASE %WM_COMMAND
                            SELECT CASE AS LONG CB.CTL
                            CASE %IDOK
                               IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                                   sTmp = REPEAT$(1000000, "123" + $CRLF + $CRLF + $CRLF + "abc" + $CRLF + "def" + $CRLF + $CRLF + "ghi" + $CRLF + "jkl" + $CRLF + $CRLF)
                                   MSGBOX LEFT$(sTmp, 31) + $CRLF + "Length: " + FORMAT$(LEN(sTmp)) + " bytes."
                      
                                   t = TIMER
                                   sTmp = RemoveLineFeedInParagraph(sTmp)
                                   t = TIMER - t
                      
                                   MSGBOX LEFT$(sTmp, 28) + _
                                          $CRLF + "Length: " + FORMAT$(LEN(sTmp)) + " bytes." + _
                                          $CRLF + "Time: " + FORMAT$(t, "0.0000") + " s."
                               END IF
                      
                            CASE %IDCANCEL
                               IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN 'end prog
                                  DIALOG END CB.HNDL
                               END IF
                            END SELECT
                      
                        END SELECT
                      END FUNCTION
                      
                      
                      '====================================================================
                      ' Remove single line feeds in paragraphs
                      ' Can be useful if a text is to be pasted into a word processor,
                      ' where paragraphs often are separated by minimun 2 line feeds.
                      '--------------------------------------------------------------------
                      FUNCTION RemoveLineFeedInParagraph(BYVAL sText AS STRING) AS STRING
                        LOCAL Ac, Bc AS LONG, pLet1, pLet2 AS BYTE PTR
                      
                        pLet1 = STRPTR(sText)
                        pLet2 = pLet1
                      
                        WHILE @pLet1[Ac]
                            IF @pLet1[Ac] = 13 THEN         ' $CRLF
                                IF @pLet1[Ac+2] <> 13 THEN  ' $CRLF was single
                                    @pLet2[Bc] = 32         ' replace $CRLF with $SPC
                                    Ac += 2                 ' move past $CRLF
                                    Bc += 1                 ' move past $SPC
                                ELSE                        ' Else $CRLF + $CRLF
                                    POKE LONG, pLet2 + Bc, PEEK(LONG, pLet1 + Ac)  ' $CRLF + $CRLF = 4 bytes = 1 Long
                                    Ac += 4 : Bc += 4       ' move ahead
                                END IF
                            END IF
                            @pLet2[Bc] = @pLet1[Ac]
                            INCR Ac : INCR Bc
                        WEND
                      
                        IF Bc > 1 THEN DECR Bc
                        FUNCTION = LEFT$(sText, Bc) ' return result
                      END FUNCTION

                      Comment


                      • #12
                        Howdy, Borje!

                        Yep, you have the gist of it right and thanks for the function. I did a quick test and it seems to work as desired.

                        ' Can be useful if a text is to be pasted into a word processor, where paragraphs often are separated by minimun 2 line feeds.
                        I've not done a speed test, but by comparison to the REPLACE options it seemed noticeably faster!!

                        Comment

                        Working...
                        X