Author Topic: Filtering strings . . .  (Read 5387 times)

0 Members and 1 Guest are viewing this topic.

jbuzbee

  • Swamp Rat
  • Posts: 851
Filtering strings . . .
« on: March 18, 2009, 12:02:32 PM »
How would I accomplish the following:

I read in a list of strings from a text file including blank lines - the blank lines help with reading the info:


Code: [Select]
01          INTERIOR KEYNOTES

01.001    SCHEDULED DOOR
01.002    WALL PARTITION

01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME
01.101    TEMPERED GLASS

01.200    BLH, BLAH, BLAH

02          EXTERIOR KEYNOTES 

. . .

So in a listbox control I only want to show the 01 keynotes.  The code I have doesn't recognize the blank spaces so it messes up the formating.  I think I need to use a while loop to know when I've left the 01 keynotes and stop looking but can't figure it out.  I don't need code, maybe a pseudo code outline.

Thanks for any help!
James Buzbee
Windows 8

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Filtering strings . . .
« Reply #1 on: March 18, 2009, 12:07:49 PM »
Why not use ' wcmatch ' with a pattern of ' 01* '?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #2 on: March 18, 2009, 02:19:01 PM »
If the blank line come in as "" then use
(vl-remove "" lst-of-strings)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10649
Re: Filtering strings . . .
« Reply #3 on: March 18, 2009, 02:54:19 PM »
^^ Or dont even store it in the first place (use T.Willey's idea).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Filtering strings . . .
« Reply #4 on: March 18, 2009, 03:01:13 PM »
Quote from: OP
read in a list of strings from a text file including blank lines - the blank lines help with reading the info:
Quote from: OP
The code I have doesn't recognize the blank spaces so it messes up the formating.

Sounds like they need the blank lines to me. :)

TheSwamp.org  (serving the CAD community since 2003)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #5 on: March 18, 2009, 03:20:46 PM »
I though he meant that the blank line helped reading that data file when editing it.  :-o
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #6 on: March 18, 2009, 03:50:30 PM »
My file reader. Reads the entire file into a list before processing the list.

Code: [Select]
;;  return only lines that start with "01"
(defun c:frtest (/ fname fn ln AllLines lst)
  (setq fname "MyFile.txt"
        prefix "01"
        pflen  (strlen prefix))
 
  (if (setq fn (findfile fname)) ; only if the file is found
    (progn ; fn contains the full path
      (setq fn (open fn "r")) ; open file for reading
      ;;  for speed read all the lines in the file
      (while (setq ln (read-line fn))
(setq AllLines (cons ln AllLines))
      )
      (close fn) ; close the open file handle
      (foreach ln AllLines ; note AllLines is reversed
        ;;  remove leading and trailing tabs & spaces
        (setq ln (vl-string-trim " \t" ln))
        ;;  exclude empty & non numeric lines
        (if (and (/= ln "")
                 (= (substr ln 1 pflen) prefix)
            )
          (setq lst (cons ln lst)) ;  collect the line
        )
      )
    )
  )
 lst
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: Filtering strings . . .
« Reply #7 on: March 18, 2009, 03:58:32 PM »
I think I'm confusing everyone  :?

When "filtered" I want this:

Code: [Select]
01.001    SCHEDULED DOOR
01.002    WALL PARTITION

01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME
01.101    TEMPERED GLASS

01.200    BLH, BLAH, BLAH

not this:

Code: [Select]
01.001    SCHEDULED DOOR
01.002    WALL PARTITION
01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME
01.101    TEMPERED GLASS
01.200    BLH, BLAH, BLAH

Does that make any more sense?
James Buzbee
Windows 8

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Filtering strings . . .
« Reply #8 on: March 18, 2009, 04:04:50 PM »
"Peanut butter"... silly architects.   :roll:
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

JohnK

  • Administrator
  • Seagull
  • Posts: 10649
Re: Filtering strings . . .
« Reply #9 on: March 18, 2009, 04:28:53 PM »
jbuzbee , I could have sworn that i gave you a file reader once in a PM but anyways...

Code: [Select]
(defun filereader (str file)
  ;; filereader
  ;;
  ;; Reads all lines in a file into a list.
  ;;
  ;;
  ;;      ( (lambda ( / f my-list )
  ;;          (setq f (open "c:\\Example.ini" "R"))
  ;;          (setq my-list
  ;;              (apply
  ;;                'append
  ;;                   (iniread (read-line f) f)))
  ;;          (close f)
  ;;          my-list ) )
  ;;     
  ;; => ("var1=val1" "var2=val2" "var4=val4")
  ;;
  ;; By: John (7) K
  ;;
  ( (lambda (s f)
      (if s
        (cons
            (list s)
          (filereader (read-line f) f))))
   str
   file ) )

;; one example of how to read from one file and write to another.

 ( (lambda ( / f )
     (setq f (open "c:\\Test.txt" "R"))
     (setq my-list
         (apply
            'append
               (filereader (read-line f) f)))
           (close f)

         (setq f (open "c:\\Test-output.txt" "W"))
         (foreach s my-list
   (write-line s f))
     (close f)) )
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #10 on: March 18, 2009, 04:31:45 PM »
OK, maybe this
Code: [Select]
;;  return only lines that start with "01"
(defun c:frtest (/ fname fn ln AllLines lst blank)
  (setq fname "MyFile.txt"
        prefix "01"
        pflen  (strlen prefix))
  
  (if (setq fn (findfile fname)) ; only if the file is found
    (progn ; fn contains the full path
      (setq fn (open fn "r")) ; open file for reading
      ;;  for speed read all the lines in the file
      (while (setq ln (read-line fn))
(setq AllLines (cons ln AllLines))
      )
      (close fn) ; close the open file handle
      (foreach ln (reverse AllLines)
        ;;  remove leading and trailing tabs & spaces
        (setq ln (vl-string-trim " \t" ln))
        ;;  filter
        (cond
          ((and (not blank) (= ln ""))
           (setq lst (cons " " lst)) ;  add one space line
           (setq blank t)
          )
          ((= (substr ln 1 pflen) prefix)
           (setq lst (cons ln lst)) ;  collect the line
           (setq blank nil)
          )
          (blank (setq blank t))
        )
      )
    )
  )
 (reverse lst)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Filtering strings . . .
« Reply #11 on: March 18, 2009, 04:32:31 PM »
Perhaps I'm not understanding, but given a list of strings, perhaps harvested from a file, this is all that's needed:

Code: [Select]
(vl-remove-if-not
   '(lambda ( x ) (wcmatch (vl-string-trim " \t" x) "01`.###*"))   
   '(
        "01          INTERIOR KEYNOTES"
        ""
        "01.001    SCHEDULED DOOR"
        "01.002    WALL PARTITION"
        ""
        "01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
        "01.101    TEMPERED GLASS"
        ""
        "01.200    BLH, BLAH, BLAH"
        ""
        "02          EXTERIOR KEYNOTES "
        "..."
    )
)

"01.001    SCHEDULED DOOR"
"01.002    WALL PARTITION"
"01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
"01.101    TEMPERED GLASS"
"01.200    BLH, BLAH, BLAH"

If you want to retain the blank lines just change the wcmatch pattern to "01`.###*,".
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #12 on: March 18, 2009, 04:35:06 PM »
Michael he wants the blank lines included, I think. 8-)
Although they need to be of one space character.

John, it is the filtering he is struggling with.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Filtering strings . . .
« Reply #13 on: March 18, 2009, 04:37:04 PM »
Yep, ergo the last sentence. :)

But thanks for the heads up Alan. :)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10649
Re: Filtering strings . . .
« Reply #14 on: March 18, 2009, 04:39:38 PM »
Michael he wants the blank lines included, I think. 8-)
Although they need to be of one space character.

John, it is the filtering he is struggling with.

Code: [Select]
(defun filereader (str file)
      (if str
        (cons
  (if (or (wcmatch str "01`.###*" ) (eq str ""))
            (list str))
          (filereader (read-line file) file))))
Like this? ...im lost.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10649
Re: Filtering strings . . .
« Reply #15 on: March 18, 2009, 04:41:11 PM »
Michael he wants the blank lines included, I think. 8-)
Although they need to be of one space character.

John, it is the filtering he is struggling with.

Code: [Select]
(defun filereader (str file)
      (if str
        (cons
  (if (or (wcmatch str "01`.###*" ) (eq str ""))
            (list str))
          (filereader (read-line file) file))))
Like this? ...im lost.


EDIT:
MP has a better filter!
> If you want to retain the blank lines just change the wcmatch pattern to "01`.###*,".
Good one!
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #16 on: March 18, 2009, 04:49:55 PM »
Let's play "What If"
What if there are 100 lines in the data file & 20% are blank lines?
I don't think he wanted ALL the blank lines.  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10649
Re: Filtering strings . . .
« Reply #17 on: March 18, 2009, 04:54:13 PM »
...Im going home.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #18 on: March 18, 2009, 05:11:05 PM »
Was it something I said?
Just kidding. :-)

My strategy is to allow the first & last blank line to be added to the list as well as any single blank line found within the target prefix.
You could strip off the first & last easy enough. I don't allow for two or more blank lines in secession.
My test file:
Code: [Select]
00          Header
00.001    Subheader

01          INTERIOR KEYNOTES

01.001    SCHEDULED DOOR
01.002    WALL PARTITION

01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME
01.101    TEMPERED GLASS

01.200    BLH, BLAH, BLAH

02          EXTERIOR KEYNOTES 

03

04



. . .

Result:
Code: [Select]
(     " "
     "01          INTERIOR KEYNOTES"  
     " "
     "01.001    SCHEDULED DOOR"  
     "01.002    WALL PARTITION"
     " "
     "01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
     "01.101    TEMPERED GLASS"  
     " "
     "01.200    BLH, BLAH, BLAH"  
     " "
    )
« Last Edit: March 18, 2009, 05:14:43 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Filtering strings . . .
« Reply #19 on: March 18, 2009, 05:18:29 PM »
allow the first & last blank line to be added to the list as well as any single blank line found within the target prefix.

Is that really what he wants? If so perhaps:

Code: [Select]
(defun CleanUpIsleFour ( lst / flag )
    (vl-remove-if-not
       '(lambda ( x )
            (or
                (and
                    (wcmatch (setq x (vl-string-trim " \t" x)) "01`.###*")
                    (null (setq flag nil))
                )
                (and
                    (eq x "")
                    (null flag)
                    (setq flag t)
                )
            )
        )
        lst
    )
)

Code: [Select]
(CleanUpIsleFour
   '(
        ""
        ""
        ""
        "01          INTERIOR KEYNOTES"
        ""
        ""
        ""
        "01.001    SCHEDULED DOOR"
        "01.002    WALL PARTITION"
        ""
        ""
        ""
        "01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
        "01.101    TEMPERED GLASS"
        ""
        ""
        ""
        "01.200    BLH, BLAH, BLAH"
        ""
        ""
        ""
        "02          EXTERIOR KEYNOTES "
        ""
        ""
        ""
    )
)

""
"01.001    SCHEDULED DOOR"
"01.002    WALL PARTITION"
""
"01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
"01.101    TEMPERED GLASS"
""
"01.200    BLH, BLAH, BLAH"
""


/shrug
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Filtering strings . . .
« Reply #20 on: March 18, 2009, 05:26:40 PM »
Maybe this?

Code: [Select]
(defun ReadFile ( fullPath ftrPat / Opened tempStr StrList)
   
    (setq Opened (open fullPath "r"))
    (while (setq tempStr (read-line Opened))
        (if (wcmatch tempStr ftrPat)
            (progn
                (setq StrList
                    (cons
                        (if (= tempStr "")
                            " "
                            tempStr
                        )
                        StrList
                    )
                )
                (while (setq tempStr (read-line Opened))
                    (if
                        (or
                            (wcmatch tempStr ftrPat)
                            (= tempStr "")
                        )
                        (setq StrList
                            (cons
                                (if (= tempStr "")
                                    " "
                                    tempStr
                                )
                                StrList
                            )
                        )
                    )
                )
            )
        )
    )
    (close Opened)
    StrList
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #21 on: March 18, 2009, 05:28:30 PM »
Very nice Michael.
Yes I think that is it.
See example.
http://www.theswamp.org/index.php?topic=27880.msg334605#msg334605
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Filtering strings . . .
« Reply #22 on: March 18, 2009, 10:01:23 PM »
Thanks Alan. I wonder though if the leading and trailing "" items are acceptable.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Daniel J. Ellis

  • Swamp Rat
  • Posts: 811
Re: Filtering strings . . .
« Reply #23 on: March 19, 2009, 04:26:05 AM »
Bit beyond my real code, but in pseudo code would:

print out your header information
read all the lines into a list
process the list, line at a time
   If the line starts "01" grab that line into a variable
   bolt on a carriage return preceding the variable, outputting the two to a new variable
move onto the next item in the list
when finished, output the whole lot enmasse to wherever it needs to go

not do the trick?

Adding the carriage return *before* the line gives you a preceding line between your header and the first line, and eliminates a probably undesirable trailing line at the end

dJE
===
dJE

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #24 on: March 19, 2009, 09:06:34 AM »
Thanks Alan. I wonder though if the leading and trailing "" items are acceptable.
I'd say not because he is going to use the list in a DCL list box.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Filtering strings . . .
« Reply #25 on: March 19, 2009, 09:30:08 AM »
One more attempt. Using "01." as the prefix and this new version eliminated leading & trailing blank lines.
Though not near as eloquent as Michael's it gets the job done. Michael's gives me something to strive for.
Code: [Select]
;;  return only lines that start with "01."
(defun c:frtest (/ fname fn ln AllLines lst blank)
  (setq fname "MyFile.txt"
        prefix "01."
        pflen  (strlen prefix))
 
  (if (setq fn (findfile fname)) ; only if the file is found
    (progn ; fn contains the full path
      (setq fn (open fn "r")) ; open file for reading
      ;;  for speed read all the lines in the file
      (while (setq ln (read-line fn))
(setq AllLines (cons ln AllLines))
      )
      (close fn) ; close the open file handle
      (foreach ln (reverse AllLines)
        ;;  remove leading and trailing tabs & spaces
        (setq ln (vl-string-trim " \t" ln))
        ;;  filter
        (cond
          ((and blank (= ln ""))
           (setq lst (cons " " lst)) ;  add one space line
           (setq blank nil) ; disallow another blank line
          )
          ((= (substr ln 1 pflen) prefix)
           (setq lst (cons ln lst)) ;  collect the line
           (setq blank t) ; allow one blank line to follow
          )
        )
      )
    )
  )
 (if (= " " (car lst))
   (reverse (cdr lst))
   (reverse lst)
 )
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Filtering strings . . .
« Reply #26 on: March 19, 2009, 09:47:53 AM »
I'd say not because he is going to use the list in a DCL list box.

If so then perhaps:

Code: [Select]
(defun CleanUpIsleFour ( lst / result flag )

    (if
        (eq ""
            (car
                (setq result
                    (vl-remove-if-not
                       '(lambda ( x )
                            (or
                                (and
                                    (wcmatch x "01`.###*")
                                    (null (setq flag nil))
                                )
                                (and
                                    (eq x "")
                                    (null flag)
                                    (setq flag t)
                                )
                            )
                        )
                        (mapcar '(lambda ( x ) (vl-string-trim " \t" x)) lst)
                    )
                )
            )
        )
        (setq result (cdr result))
    )

    (if (eq "" (last result))
        (reverse (cdr (reverse result)))
        result
    )

)

Code: [Select]
(CleanUpIsleFour
   '(
        ""
        ""
        ""
        "01          INTERIOR KEYNOTES"
        ""
        ""
        ""
        "01.001    SCHEDULED DOOR"
        "01.002    WALL PARTITION"
        ""
        ""
        ""
        "01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
        "01.101    TEMPERED GLASS"
        ""
        ""
        ""
        "01.200    BLH, BLAH, BLAH"
        ""
        ""
        ""
        "02          EXTERIOR KEYNOTES "
        ""
        ""
        ""
    )
)

"01.001    SCHEDULED DOOR"
"01.002    WALL PARTITION"
""
"01.100    USE PEANUT BUTTER TO CAULK WINDOW FRAME"
"01.101    TEMPERED GLASS"
""
"01.200    BLH, BLAH, BLAH"


PS: Thanks for the undeserved nice words Alan.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: Filtering strings . . .
« Reply #27 on: March 19, 2009, 10:46:14 AM »
You guys are hopeless!  I said psuedo code, but no - you guy's can't pass up the oppurtunity can you?  I think there is a twelve step program for this sort of thing.



 :-D

Just kidding!  There's some pretty good code here guys, thankyou very much.  I'm not at my computer with all my source code so I'll have to try some of this stuff out tonight.  Thanks again.


(CleanUpIsleFour - pretty funny stuff MP)
James Buzbee
Windows 8