49

I am trying to use a regex for replacing text in a file (replace a full url with just protocol/domain/):

:%s/\(https\?:\/\/.*?\/\).*/\1/gc

Unfortunately .*? does not match the string, even trying to escape the ? quantifier? How should non-greedy quantifier be escaped in vim?

2
70

Vim's regex has special syntax for non-greedy versions of operators (it's kind of annoying, but you just have to memorize them): http://vimregex.com/#Non-Greedy

The non-greedy version of * is \{-}. So, simply replace .* with .\{-}:

:%s/\(https\?:\/\/.\{-}\/\).*/\1/gc
2
  • 5
    I can see now why some people prefer emacs.
    – tejasvi88
    Feb 6 at 4:59
  • 2
    What's the non-greedy version of \+ Mar 27 at 12:33
16

I prefer always breaking the problem into two steps:

/\v(https?):\/\/(.{-})\/.*        <-- Search
:%s,,Protocol:\1 - Domain:\2,g    <-- Substitution

Using very magic "\v" to avoid many backslashes, referencing the last search in substitution and changing substitution delimiter. All these changes make the code more readable.

enter image description here

2

You can also use the [^\]+/. to prevent greediness. [^/] means "match anything expect /, and + repeats that one or more times..

:%s!\v^(https?)\://([^/]+)/.*$!Protocol:\1 \t Domain:\2!g

If I have / in the regex, I will use ! as a separator so that I don't have to escape /.

Example

Let's suppose you have the following urls:

http://academy.mises.org/courses/econgd/
http://academy.mises.org/moodle/course/view.php?id=172
http://acmsel.safaribooksonline.com/book/-/9781449358204?bookview=overview
http://acmsel.safaribooksonline.com/home
http://acordes.lacuerda.net/bebo__cigala/lagrimas_negras-2.shtml
http://acordes.lacuerda.net/jose_antonio_labordeta/albada.shtml
http://anarchitext.wordpress.com/category/new-middle-east/
https://courses.edx.org/courses/course-v1%3ADelftX%2BFP101x%2B3T2015/wiki/DelftX.FP101x.3T2015/resources-and-links/
https://cseweb.ucsd.edu/classes/wi11/cse230/lectures.html
https://developer.mozilla.org/en-US/docs/CSS
https://developers.google.com/edu/python
https://developers.google.com/structured-data/testing-tool/

Applying the substitution you would get that :

Protocol:http    Domain:academy.mises.org
Protocol:http    Domain:academy.mises.org
Protocol:http    Domain:acmsel.safaribooksonline.com
Protocol:http    Domain:acmsel.safaribooksonline.com
Protocol:http    Domain:acordes.lacuerda.net
Protocol:http    Domain:acordes.lacuerda.net
Protocol:http    Domain:anarchitext.wordpress.com
Protocol:https   Domain:courses.edx.org
Protocol:https   Domain:cseweb.ucsd.edu
Protocol:https   Domain:developer.mozilla.org
Protocol:https   Domain:developers.google.com
Protocol:https   Domain:developers.google.com
1
  • 1
    I think + doesn't work it has to be \+ Mar 27 at 12:33

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .