14

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
    :help greedy would have taken you to the right help topic. :help regexp is the help describing Vim's regex flavor. – jamessan Feb 3 '15 at 22:36
18

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
4

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.