| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
11.6 Substituting text by regular expression
Global substitution in a string is done by patsubst:
- Builtin: patsubst (string, regexp, [replacement]@c)
- Searches string for matches of regexp, and substitutes replacement for each match. The syntax for regular expressions is the same as in GNU Emacs (see section Searching for regular expressions). - The parts of string that are not covered by any match of regexp are copied to the expansion. Whenever a match is found, the search proceeds from the end of the match, so a character from string will never be substituted twice. If regexp matches a string of zero length, the start position for the search is incremented, to avoid infinite loops. - When a replacement is to be made, replacement is inserted into the expansion, with ‘\n’ substituted by the text matched by the nth parenthesized sub-expression of patsubst, for up to nine sub-expressions. The escape ‘\&’ is replaced by the text of the entire regular expression matched. For all other characters, ‘\’ treats the next character literally. A warning is issued if there were fewer sub-expressions than the ‘\n’ requested, or if there is a trailing ‘\’. - The replacement argument can be omitted, in which case the text matched by regexp is deleted. - The macro - patsubstis recognized only with parameters.
| patsubst(`GNUs not Unix', `^', `OBS: ') ⇒OBS: GNUs not Unix patsubst(`GNUs not Unix', `\<', `OBS: ') ⇒OBS: GNUs OBS: not OBS: Unix patsubst(`GNUs not Unix', `\w*', `(\&)') ⇒(GNUs)() (not)() (Unix)() patsubst(`GNUs not Unix', `\w+', `(\&)') ⇒(GNUs) (not) (Unix) patsubst(`GNUs not Unix', `[A-Z][a-z]+') ⇒GN not patsubst(`GNUs not Unix', `not', `NOT\') error-->m4:stdin:6: Warning: trailing \ ignored in replacement ⇒GNUs NOT Unix | 
Here is a slightly more realistic example, which capitalizes individual
words or whole sentences, by substituting calls of the macros
upcase and downcase into the strings.
- Composite: upcase (text)
- Composite: downcase (text)
- Composite: capitalize (text)
- Expand to text, but with capitalization changed: - upcasechanges all letters to upper case,- downcasechanges all letters to lower case, and- capitalizechanges the first character of each word to upper case and the remaining characters to lower case.
First, an example of their usage, using implementations distributed in ‘m4-1.4.16/examples/capitalize.m4’.
| $ m4 -I examples include(`capitalize.m4') ⇒ upcase(`GNUs not Unix') ⇒GNUS NOT UNIX downcase(`GNUs not Unix') ⇒gnus not unix capitalize(`GNUs not Unix') ⇒Gnus Not Unix | 
Now for the implementation.  There is a helper macro _capitalize
which puts only its first word in mixed case.  Then capitalize
merely parses out the words, and replaces them with an invocation of
_capitalize.  (As presented here, the capitalize macro has
some subtle flaws.  You should try to see if you can find and correct
them; or see section Answers).
| $ m4 -I examples undivert(`capitalize.m4')dnl ⇒divert(`-1') ⇒# upcase(text) ⇒# downcase(text) ⇒# capitalize(text) ⇒# change case of text, simple version ⇒define(`upcase', `translit(`$*', `a-z', `A-Z')') ⇒define(`downcase', `translit(`$*', `A-Z', `a-z')') ⇒define(`_capitalize', ⇒ `regexp(`$1', `^\(\w\)\(\w*\)', ⇒ `upcase(`\1')`'downcase(`\2')')') ⇒define(`capitalize', `patsubst(`$1', `\w+', `_$0(`\&')')') ⇒divert`'dnl | 
While regexp replaces the whole input with the replacement as
soon as there is a match, patsubst replaces each
occurrence of a match and preserves non-matching pieces:
| define(`patreg', `patsubst($@) regexp($@)')dnl patreg(`bar foo baz Foo', `foo\|Foo', `FOO') ⇒bar FOO baz FOO ⇒FOO patreg(`aba abb 121', `\(.\)\(.\)\1', `\2\1\2') ⇒bab abb 212 ⇒bab | 
Omitting regexp evokes a warning, but still produces output; contrast this with an empty regexp argument.
| patsubst(`abc') error-->m4:stdin:1: Warning: too few arguments to builtin `patsubst' ⇒abc patsubst(`abc', `') ⇒abc patsubst(`abc', `', `\\-') ⇒\-a\-b\-c\- | 
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
