LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 04-20-2015, 12:05 PM   #1
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch, Lubuntu 18.04 OpenSUSE Leap 15.x
Posts: 516

Rep: Reputation: 24
vim regex problem :s/^\s*\(.\)\+/\\\1/g


I need to prepend a backslash \ to each character in a string, excluding any leading whitespace. I believed the following would do the trick.
Code:
:s/^\s*\(.\)\+/\\\1/g
but it produces this result for the string shown
Code:
   abcde
\e
i.e. it shows only the last such replacement, not each of them.

Vim provides 2 regex engines, which you can access explicitly by prepending the search string with either '\%#=1' or '\%#=2'. Both produce the same result.

Could someone explain what I am doing wrong here
 
Old 04-20-2015, 12:58 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,081
Blog Entries: 23

Rep: Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063
Quote:
Originally Posted by porphyry5 View Post
I need to prepend a backslash \ to each character in a string, excluding any leading whitespace. I believed the following would do the trick.
Code:
:s/^\s*\(.\)\+/\\\1/g
but it produces this result for the string shown
Code:
   abcde
\e
i.e. it shows only the last such replacement, not each of them.

Vim provides 2 regex engines, which you can access explicitly by prepending the search string with either '\#=1' or '\#=2'. Both produce the same result.

Could someone explain what I am doing wrong here
Your regex tells it to remove space and only capture the last character, (.), hence \e. The trailing + matches multiple characters, but only captures and replaces the last one.

Try this, assuming that you want to leave surrounding space intact:

Code:
s/\([^ \t]\)/\\\1/g

...
   \a\b\c\d\e
Or to remove leading whitespace:

Code:
s/^\s*\([^ \t]\)/\\\1/g

...
\a\b\c\d\e
(Fixed: Remove the ^, typed here in error!)

Last edited by astrogeek; 04-20-2015 at 02:13 PM. Reason: Noted error ^
 
1 members found this post helpful.
Old 04-20-2015, 01:52 PM   #3
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch, Lubuntu 18.04 OpenSUSE Leap 15.x
Posts: 516

Original Poster
Rep: Reputation: 24
Quote:
Originally Posted by astrogeek View Post
Your regex tells it to remove space and only capture the last character, (.), hence \e. The trailing + matches multiple characters, but only captures and replaces the last one.

Try this, assuming that you want to leave surrounding space intact:

Code:
s/\([^ \t]\)/\\\1/g

...
   \a\b\c\d\e
Or to remove leading whitespace:

Code:
s/^\s*\([^ \t]\)/\\\1/g

...
\a\b\c\d\e
I tried your second suggestion, but it gave me
Code:
s/^\s*\([^ \t]\)/\\\1/g
\abcde
which seemed reasonable, because '[...]' should just access one character, so I then did
Code:
s/^\s*\([^ \t]\)\+/\\\1/g
\e
the same as my original effort, and
Code:
s/^\s*\([^ \t]\+\)/\\\1/g
\abcde
But finally this did work
Code:
s/\S/\\&/g
\a\b\c\d\e
and I guess it translates as
\S the next non-whitespace character
\\& a backslash in front of current search result
/g do every one in the line

That gave me the clue that fixing it to the start of the line was the problem, because both of these work too.
Code:
s/\([^\t ]\)/\\\1/g
s/\s*\(.\)/\\\1/g
Many thanks for your help.

Last edited by porphyry5; 04-20-2015 at 02:09 PM. Reason: more solutions
 
Old 04-20-2015, 02:11 PM   #4
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,081
Blog Entries: 23

Rep: Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063Reputation: 4063
Quote:
Originally Posted by porphyry5 View Post
More solutions

I tried your second suggestion, but it gave me
Code:
s/^\s*\([^ \t]\)/\\\1/g
\abcde
which seemed reasonable, because '[...]' should just access one character...
You are correct - I don't know why I added the caret (^) here, I did not have it in my test case - things done in haste! Remove the caret and it will work as advertized...

Glad you found a solution.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Confusing issue with Perl regEx - Regex check seems to require variable being set EnderX Programming 1 09-07-2013 04:36 AM
[SOLVED] differences between shell regex and php regex and perl regex and javascript and mysql golden_boy615 Linux - General 2 04-19-2011 01:10 AM
Perl to find regex and print following 5 lines after regex casperdaghost Linux - Newbie 3 08-29-2010 08:08 PM
[SOLVED] A problem with vim and vim’s macros w1k0 Linux - Software 1 11-14-2009 12:13 PM
Editor comparison: vim VS vim-lite, Cleaning vim Ruler2112 *BSD 4 04-13-2009 04:26 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 02:13 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration