Yes and no. Depends a lot on the complexity of the documents. Textile has a lot of various formats for links and Markdown has it's share.
Keeping pattern
When you do a substitute you can capture parts of the matched text in groups:
The groups are numbered from one, zero being the whole text. One reference them by backslash + number, e.g. \1
, \2
. (Note that different dialects uses different syntax, JavaScript for example uses $1
, $2
)
These groups can further be used in the replacement portion of substitute. From above:
So if you have for example "Some Title":/some/path
and do:
"\([^"]*\)":\([a-z/]*\)
||_______|||__________|
| | | |
| | | +------ Group 2: match a-z and /
| | +------------ Match ":
| +----------------- Group 1: match anything but "
+---------------------- Match "
You can use the captured groups in the replacement part, for example:
%s/"\([^"]*\)":\([a-z/]*\)/GROUP0: \0\rGROUP1: \1\rGROUP2: \2
Result is:
GROUP0: "Some Title":/some/path
GROUP1: Some Title
GROUP2: /some/path
See :h \(
and the rest of the pattern.txt
help-file. Also note the groups can be nested. One can use \%(
for non-numbered groups etc.
You can also use the group AKA back-reference / sub-expression in the search/match portion.
For example \(abra\)cad\1
would match abracadabra
.
It is usually a good idea to use the confirm
flag. E.g.: %s/foo/bar/c
- the c
at the end makes Vim ask before each + one can skip, do the rest etc. g
for global is also often useful if one need to replace same thing more then once per line.
If you are new to RegExp it is a good idea to play around with one of the many online tools:
- various other tools, guides etc. Only be aware that there are different versions, syntax etc.
Vim has it's own + a lot of extra niceties - but the basic concept is OK to train on using such tools.
Complexity
Substitution patterns can quickly become very complex. For fun; Say one have:
"Wikipedia":https://en.wikipedia.org/
"link text":/example
"link text(with title)":https://example.com/
"(classname)link text(title tooltip)":mailto:someone@example.com
One could do:
s/"\%(\%((\)\([^)]*\)\%()\)\)\?\([^("]\+\)\%(\%((\)\([^)]*\)\%()\)\)\?":\([a-z:/@.%#?+&-]\+\)/\0:\r Class: \1\r Text : \2\r Title: \3\r URL : \4\r
To get:
"Wikipedia":https://en.wikipedia.org/:
Class:
Text : Wikipedia
Title:
URL : https://en.wikipedia.org/
"link text":/example:
Class:
Text : link text
Title:
URL : /example
"link text(with title)":https://example.com/:
Class:
Text : link text
Title: with title
URL : https://example.com/
"(classname)link text(title tooltip)":mailto:someone@example.com:
Class: classname
Text : link text
Title: title tooltip
URL : mailto:someone@example.com
But that far from cover all + does not have a way to check for faults etc.
Regexp is very very powerful but not the best tool for all tasks.
If for anything one usually have to work very methodically and know the mediums at task very good.
Break it up
Once it becomes a tad complex it is best to write a function where one can break it up and make it more readable etc. Use comments and descriptive names. As a simple example from the above (Here converting to HTML anchors):
(Extra quotes at end of comments as SE does not recognize Vim's one line comments.)
fun! s:MyLinkConverter()
" Groups: 1 "
let match_class_or_title =
\ '\%('
\ . '\%((\)'
\ . '\([^)]*\)'
\ . '\%()\)'
\ . '\)\?'
" Groups: 1 "
let match_text = '\([^("]\+\)'
" Groups: 1 "
let match_href = '\([A-Za-z:/@.%#?+&-]\+\)'
" Groups: "
" 1: class "
" 2: text "
" 3: title "
" 4: href "
let pat_search =
\ '"'
\ . match_class_or_title
\ . match_text
\ . match_class_or_title
\ . '":'
\ . match_href
let pat_replace =
\ '<a href="\4" title="\3" class="\1">\2<\/a>'
exe "'<,'>s/" . pat_search . "/" . pat_replace . "/gc"
endfun
command! -range MyLinkConverter call s:MyLinkConverter()
(SE also strip and mangles tabs and completely disrespect anyone using tabs in code, so I had to reformat it with spaces.) - (So sorry for the spaces over tabs)
Converters
Have not converted this kind of documents. A quick search hints to https://github.com/jgm/pandoc for one tool. There is also an extra tool:
https://github.com/jldec/tomd - but status, usage etc. of either of these is not my domain.