Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: function support for regular expression substitution



While I'm at it.

Index: Functions/Misc/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Misc/.distfiles,v
retrieving revision 1.16
diff -u -r1.16 .distfiles
--- Functions/Misc/.distfiles	16 Dec 2009 12:12:57 -0000	1.16
+++ Functions/Misc/.distfiles	18 Jan 2010 12:40:45 -0000
@@ -10,6 +10,7 @@
 mere
 nslookup
 promptnl
+regexp-replace
 relative
 run-help
 run-help-git
Index: Functions/Misc/regexp-replace
===================================================================
RCS file: Functions/Misc/regexp-replace
diff -N Functions/Misc/regexp-replace
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Functions/Misc/regexp-replace	18 Jan 2010 12:40:45 -0000
@@ -0,0 +1,35 @@
+# Replace all occurrences of a regular expression in a variable.  The
+# variable is modified directly.  Respects the setting of the
+# option RE_MATCH_PCRE.
+#
+# First argument: *name* (not contents) of variable.
+# Second argument: regular expression
+# Third argument: replacement string.  This can contain all forms of
+# $ and backtick substitutions; in particular, $MATCH will be replaced
+# by the portion of the string matched by the regular expression.
+
+integer pcre
+
+[[ -o re_match_pcre ]] && pcre=1
+
+emulate -L zsh
+(( pcre )) && setopt re_match_pcre
+
+# $4 is the string to be matched
+4=${(P)1}
+# $5 is the final string
+5=
+local MATCH MBEGIN MEND
+local -a match mbegin mend
+
+while [[ -n $4 ]]; do
+  if [[ $4 =~ $2 ]]; then
+    5+=${4[1,MBEGIN-1]}${(e)3}
+    4=${4[MEND+1,-1]}
+  else
+    break
+  fi
+done
+5+=$4
+
+eval ${1}=${(q)5}
Index: Functions/Zle/replace-string-again
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Zle/replace-string-again,v
retrieving revision 1.2
diff -u -r1.2 replace-string-again
--- Functions/Zle/replace-string-again	3 Apr 2008 11:39:11 -0000	1.2
+++ Functions/Zle/replace-string-again	18 Jan 2010 12:40:46 -0000
@@ -13,7 +13,7 @@
   return 1
 fi
 
-if [[ $curwidget = *pattern* ]]; then
+if [[ $curwidget = *(pattern|regex)* ]]; then
     local rep2
     # The following horror is so that an & preceded by an even
     # number of backslashes is active, without stripping backslashes,
@@ -38,8 +38,14 @@
 	rep=${match[5]}
     done
     rep2+=$rep
-    LBUFFER=${LBUFFER//(#bm)$~_replace_string_src/${(e)rep2}}
-    RBUFFER=${RBUFFER//(#bm)$~_replace_string_src/${(e)rep2}}
+    if [[ $curwidget = *regex* ]]; then
+      autoload -U regexp-replace
+      regexp-replace LBUFFER $_replace_string_src $rep2
+      regexp-replace RBUFFER $_replace_string_src $rep2
+    else
+      LBUFFER=${LBUFFER//(#bm)$~_replace_string_src/${(e)rep2}}
+      RBUFFER=${RBUFFER//(#bm)$~_replace_string_src/${(e)rep2}}
+    fi
 else
     LBUFFER=${LBUFFER//$_replace_string_src/$_replace_string_rep}
     RBUFFER=${RBUFFER//$_replace_string_src/$_replace_string_rep}
Index: Doc/Zsh/contrib.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v
retrieving revision 1.106
diff -u -r1.106 contrib.yo
--- Doc/Zsh/contrib.yo	16 Jan 2010 16:28:30 -0000	1.106
+++ Doc/Zsh/contrib.yo	18 Jan 2010 12:40:46 -0000
@@ -1570,14 +1570,14 @@
 tindex(replace-pattern)
 xitem(tt(replace-string), tt(replace-pattern))
 item(tt(replace-string-again), tt(replace-pattern-again))(
-The function tt(replace-string) implements two widgets.
+The function tt(replace-string) implements three widgets.
 If defined under the same name as the function, it prompts for two
 strings; the first (source) string will be replaced by the second
 everywhere it occurs in the line editing buffer.
 
 If the widget name contains the word `tt(pattern)', for example by
 defining the widget using the command `tt(zle -N replace-pattern
-replace-string)', then the replacement is done by pattern matching.  All
+replace-string)', then the matching is performed using zsh patterns.  All
 zsh extended globbing patterns can be used in the source string; note
 that unlike filename generation the pattern does not need to match an
 entire word, nor do glob qualifiers have any effect.  In addition, the
@@ -1588,6 +1588,12 @@
 `tt(\{)var(N)tt(})' may be used to protect the digit from following
 digits.
 
+If the widget instead contains the word `tt(regex)' (or `tt(regexp)'),
+then the matching is performed using regular expressions, respecting
+the setting of the option tt(RE_MATCH_PCRE) (see the description of the
+function tt(regexp-replace) below).  The facilities described
+for pattern matching are also available.
+
 By default the previous source or replacement string will not be offered
 for editing.  However, this feature can be activated by setting the style
 tt(edit-previous) in the context tt(:zle:)var(widget) (for example,
@@ -1595,12 +1601,12 @@
 numeric argument forces the previous values to be offered, a negative or
 zero argument forces them not to be.
 
-The function tt(replace-string-again) can be used to repeat the
-previous replacement; no prompting is done.  As with tt(replace-string), if
-the name of the widget contains the word `tt(pattern)', pattern matching
-is performed, else a literal string replacement.  Note that the
-previous source and replacement text are the same whether pattern or string
-matching is used.
+The function tt(replace-string-again) can be used to repeat the previous
+replacement; no prompting is done.  As with tt(replace-string), if the name
+of the widget contains the word `tt(pattern)' or `tt(regex)', pattern or
+regular expression matching is performed, else a literal string
+replacement.  Note that the previous source and replacement text are the
+same whether pattern, regular expression or string matching is used.
 
 For example, starting from the line:
 
@@ -2574,6 +2580,25 @@
 
 See also the tt(pager), tt(prompt) and tt(rprompt) styles below.
 )
+findex(regexp-replace)
+item(tt(regexp-replace) var(var) var(regexp) var(replace))(
+Use regular expressions to perform a global search and replace operation
+on a variable.  If the option tt(RE_MATCH_PCRE) is not set, POSIX
+extended regular expressions are used, else Perl-compatible regular
+expressions (this requires the shell to be linked against the tt(pcre)
+library).
+
+var(var) is the name of the variable containing the string to be matched.
+The variable will be modified directly by the function.  The
+variables tt(MATCH), tt(MBEGIN), tt(MEND), tt(match), tt(mbegin), tt(mend)
+should be avoided as these are used by the regular expression code.
+
+var(regexp) is the regular expression to match against the string.
+
+var(replace) is the replacement text.  This can contain parameter, command
+and arithmetic expressions which will be replaced:  in particular, a
+reference to tt($MATCH) will be replaced by the text matched by the pattern.
+)
 findex(run-help)
 item(tt(run-help) var(cmd))(
 This function is designed to be invoked by the tt(run-help) ZLE widget,


-- 
Peter Stephenson <pws@xxxxxxx>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom



Messages sorted by: Reverse Date, Date, Thread, Author