Visual REGEXP

Visual REGEXP , by Laurent Riesterer, is a program that illustrates the mechanics of regular expressions, quickly build efficient regular expressions, etc. Currently at

Attributes

current version
3.1
release time
2006-03-07
contact
mailto:[email protected]

See Also

Description

http://laurent.riesterer.free.fr/regexp/screenshot1.png

http://laurent.riesterer.free.fr/regexp/screenshot2.png

http://laurent.riesterer.free.fr/regexp/screenshot3.png


Discussion

My raving was deleted, but I reiterate it: never mind similar tools: this app can be improved, but it can't be beaten.

RLH: I use this app all the time. I have tweaked it (wider buttons and a quit button) but other than that I really like it.

aspect: as of 2015-02-26 I have made some tiny tweaks for this so I don't have to be this guy . They are hiding behind the discussion tag below, as the 16k-char base64 encoded image on one line made fossil treat the file as binary. Thanks to LW and RLH for encouraging me to actually post this:

--- visual_regexp-3.1.tcl        2006-03-08 12:21:56.000000000 +1100
+++ visual_regexp-3.2.tcl        2015-11-04 09:19:31.019661182 +1100
@@ -1,7 +1,20 @@
+#
+# Changelog since 3.1:
+#  - remove stale manual undo code (handled by text widgets)
+#  - collapse delete/insert into a single replace to leave undo clean
+#  - get rid of extra newline from [.t get 1.0 end]
+#  - change select buttons in replace mode (only) to insert \\$x in replace.text
+#  - tag/colour inserted \\$x in replace.text
+#  - default to replace mode
+#  - bump version number to 3.2.  filename said 3.1; source said 3.0
+#
+# original was downloaded from http://laurent.riesterer.free.fr/regexp/visual_regexp-3.1.tcl
+#
+package require Tk
 package require starkit
 starkit::startup
 
-set version 3.0
+set version 3.2
 
 ###############################################################################################
 #
@@ -68,7 +81,7 @@
 # show/hide history windows on startup
 set history                                0
 # mode to use on startup (select/concat = raw, select/insert new lines = nl, replace = replace)
-set mode                                nl
+set mode                                replace
 # database of some regexp to appear in the "Insert regexp" menu
 set regexp_db {
         "URL"                        {(?:^|")(http|ftp|mailto):(?://)?(\w+(?:[\.:@]\w+)*?)(?:/|@)([^"\?]*?)(?:\?([^\?"]*?))?(?:$|")}
@@ -88,8 +101,6 @@
 #----------------------------------------------------------------------------------------------
 
 namespace eval regexp {} {
-        set data(v:undo:index) 0
-        set data(v:undo:sample) ""
         set data(v:dir) "."
         set data(v:file) "untitled.txt"
 
@@ -172,13 +183,11 @@
                                 }
                         }
 
-                        if {$tcl_platform(platform) == "windows"} {
-                                set sfont        {Courier 8};
-                                set sbfont        {Courier 8 bold};
-                        } else {
-                                set sfont        6x13;
-                                set sbfont        6x13bold;
-                        }
+                        set sfont TkFixedFont
+                        set sbfont TkFixedFontBold
+                        set fa [font actual $sfont]
+                        dict set da -weight bold
+                        font create $sbfont {*}$fa
 
                         set data(w:help)        [text .top.regexp.help \
                                 -font                                $sfont \
@@ -191,7 +200,7 @@
                         .top.regexp.help insert 1.0 "\n\n\n\n\n\n\n\n";
                         .top.regexp.help insert 1.0 {\a  alert              \n     newline     \0    char 0       \d [[:digit:]]    \A beginning of the string };
                         .top.regexp.help insert 2.0 {\b  backspace          \r     carriage    \xyz  octal code   \D [^[:digit:]]   \Z end of string };
-                        .top.regexp.help insert 3.0 {\B  synomyn for \      \t     tab                            \s [[:space:]]    \m beginning of a word};
+                        .top.regexp.help insert 3.0 {\B  synonym for \      \t     tab                            \s [[:space:]]    \m beginning of a word};
                         .top.regexp.help insert 4.0 {\cX same as X & 0x1F   \uwxyz unicode     \x    backref      \S [^[:space:]]   \M end of a word};
                         .top.regexp.help insert 5.0 {\e  ESC                \v     vert tab                       \w [[:alnum:]_]   \y beginning or end of a word};
                         .top.regexp.help insert 6.0 {\f  form feed          \xhhh  hexa code                      \W [^[:alnum:]_]  \Y not beginning or end of a word};
@@ -356,6 +365,7 @@
 
                         foreach level $data(v:levels) color $colors {
                                 $data(w:regexp) tag configure $level -foreground $color;
+                                $data(w:replace) tag configure $level -foreground $color;
                                 $data(w:history) tag configure $level -foreground $color;
                                 $data(w:sample) tag configure $level -foreground $color;
                         }
@@ -693,6 +703,10 @@
 proc regexp::select {level} {
 variable data
 
+        if {$data(v:mode) eq "replace"} {
+                $data(w:replace) insert insert \\\\$level e$level
+                return
+        }
         # update
         go
         if {[llength $data(v:result)] == 0} {
@@ -722,8 +736,7 @@
                 }
                 incr i
         }
-        $data(w:sample) delete 1.0 end
-        $data(w:sample) insert 1.0 $newsample
+        $data(w:sample) replace 1.0 end $newsample
         # update with regexp
         go
 }
@@ -809,48 +822,6 @@
 }
 
 #----------------------------------------------------------------------------------------------
-#        Undo/redo (quick and dirty UNDO/REDO support)
-#----------------------------------------------------------------------------------------------
-
-proc regexp::undo:sample {} {
-variable data
-
-        # display result
-        $data(w:sample) delete 1.0 end
-        $data(w:sample) insert 1.0 $data(v:undo:sample)
-        # colorize
-        go
-}
-
-proc regexp::unredo:regexp {dir} {
-variable data
-
-        set index [expr ($data(v:undo:index)+$dir) % 100]
-        if {![info exists data(v:undo:r$index)]} {
-                return
-        }
-        set data(v:undo:index) $index
-
-        set t $data(w:regexp)
-        $t delete 1.0 end
-        $t insert 1.0 [lindex $data(v:undo:r$index) 1]
-        $t mark set insert [lindex $data(v:undo:r$index) 0]
-}
-
-proc regexp::undo:regexp:compute {w k a} {
-variable data
-
-        if {[string match -nocase "*control*" $k]
-                        || [string match -nocase "*shift*" $k]
-                        || [string match -nocase "*alt*" $k]} {
-                return
-        }
-
-        set data(v:undo:r$data(v:undo:index)) [list [$w index insert] [$w get 1.0 end-1char]]
-        set data(v:undo:index) [expr ($data(v:undo:index)+1) % 100]
-}
-
-#----------------------------------------------------------------------------------------------
 #        Replace
 #----------------------------------------------------------------------------------------------
 
@@ -864,23 +835,24 @@
                 return
         }
 
-        # get sample & store it for undo
         set sample [$data(w:sample) get 1.0 end]
-        set data(v:undo:sample) $sample
-        set result [eval regsub $data(v:all) \
-                                                $data(v:line) $data(v:lineanchor) $data(v:linestop) \
-                                                $data(v:nocase) -- \
-                                                [list $exp] [list $sample] [list [subst -nocommands -novariables $subst]] sample]
+        regsub {(.*)\n} $sample {\1} sample
+        set subst [subst -nocommands -novariables $subst]
+
+        set flags [list {*}$data(v:all)  {*}$data(v:line) {*}$data(v:lineanchor) {*}$data(v:linestop) {*}$data(v:nocase)]
+        set result [regsub {*}$flags -- $exp $sample $subst sample]
+
         set regexp::data(v:nbreplace) "$result replaced"
         # display result
-        $data(w:sample) delete 1.0 end
-        $data(w:sample) insert 1.0 $sample
+        #$data(w:sample) edit separator
+        $data(w:sample) replace 1.0 end $sample
+        #$data(w:sample) edit separator
 }
 
 proc regexp::replace:toggle {} {
 variable data
 
-        if {$regexp::data(v:mode) == "replace"} {
+        if {$data(v:mode) == "replace"} {
                 bind $data(w:regexp) <Tab> "focus $data(w:replace); break;"
                 bind $data(w:regexp) <Shift-Tab> "focus $data(w:sample); break;"
                 catch { bind $data(w:regexp) <ISO_Left_Tab> "focus $data(w:sample); break;" }
@@ -918,8 +890,7 @@
 proc regexp::regexp:set {text} {
 variable data
 
-        $data(w:regexp) delete 1.0 end
-        $data(w:regexp) insert 1.0 $text
+        $data(w:regexp) replace 1.0 end $text
 }
 
 proc regexp::regexp:colorize {} {
@@ -1138,8 +1109,7 @@
 proc regexp::sample:set {text} {
 variable data
 
-        $data(w:sample) delete 1.0 end
-        $data(w:sample) insert 1.0 $text
+        $data(w:sample) replace 1.0 end $text
         set data(v:undo:sample) $text
 }
 
@@ -1471,8 +1441,7 @@
 variable data
 
         set words [$data(w:make:list) get 1.0 end-1c]
-        $data(w:make:output) delete 1.0 end
-        $data(w:make:output) insert 1.0 [make-regexp::make-regexp $words]
+        $data(w:make:output) replace 1.0 end [make-regexp::make-regexp $words]
 }
 
 proc regexp::make-regexp:ok {w} {