I am trying to delete a bunch of comments that are all in the following format:
/**
* #ngdoc
... comment body (delete me, too!)
*/
I have tried using this command: %s/\/**\n * #ngdoc.\{-}*\///g
Here is the regex without the patterns: %s/pattern1.\{-}pattern2//g
Here are the individual patterns: \/**\n * #ngdoc and *\/
When I try my pattern in vim I get the following error:
E871: (NFA regexp) Can't have a multi follow a multi !
E61: Nested *
E476: Invalid command
Thanks for any help with this regexp nightmare!
Instead of trying to cram this into one complex regex, it's much easier to search for the start of a comment and delete from there on to the end of a comment
:g/^\/\*\*$/,/\*\/$/d_
This breaks down into
:g start a global command
/^\/\*\*$/ search for start of a comment: <sol>/**<eol>
,/^\*\/$/ extend the range to the end of a comment: <sol>*/<eol>
d delete the range
_ use the black hole register (performance optimization)
Your problem is you have \{-} followed by * which are the multis referenced in the error message. Quote the *:
%s/\/\*\*\n \* #ngdoc\_.\{-}\*\/\n//g
Using embedded newlines in the pattern is the wrong approach. You should instead use an address range. Something like:
sed '\#^/\*\*$#,\#^\*/$#d' file
This will delete all lines starting from one that matches /** anchored at column 1 to the line matching */ anchored at column 1. If your comments are well behaved (eg, no trailing space after /**), this should do what you want.
Try this using gc to be careful when deleting
%s/\v\/\*\*\n\s\*\s\#ngdoc\n((\s*\n)?(\s\*.*\n)?){-}\s?\*\///gc
Match comments like
/**
* #ngdoc
* ... comment body (delete me, too!)
*
*/
My approached consists of using a macro:
qa/\/\*\*<enter><shift-v>/\*\/<enter>d
qa ........ starts recording macro "a"
/\/\*\* ... searches for the comment beginning
<Enter> ... use Ctrl-v Enter
V ......... starts visual block (until...)
/\*\/ ..... end of your comment
<Enter> ... Ctrl-v Enter agai
d ......... it will delete selected area
In order to isert etc presse followed by the keyword you want.
This question already has answers here:
Substitution of characters limited to part of each input line
(4 answers)
Closed 6 years ago.
Say I have this piece of text:
some.blah.key={{blah.woot.wiz}}
some.another.foo.key={{foo.bar.qix.name}}
+ many other lines with a variable number of words separated by dots within {{ and }}
I'd like the following outcome after replacing dots with underscores in the right part (between the {{ and }} delimiters):
some.blah.key={{blah_woot_wiz}}
some.another.foo.key={{foo_bar_qix_name}}
...
I'm looking for the appropriate regex to perform the replacement in a one-liner sedcommand`.
I'm on a lead with this one: https://regex101.com/r/8wsLHo/1 but it capture all dots, including those on the left part, which I don't want.
I tried this variation to exclude those on the left part but then it doesn't capture anything anymore: https://regex101.com/r/d7WAmX/1
You can use a loop:
sed ':a;s/\({{[^}]*\)\./\1_/;ta' file
:a defines a label "a"
ta jumps to "a" when something is replaced.
I came up with this quite complex one-liner:
sed "h;s/=.*/=/;x;s/.*=//;s/\./_/g;H;x;s/\n//"
explanations:
h: put line in hold buffer
s/=.*/=/: clobber right part after =
x: swap to put line in main buffer again, first part in hold buffer
s/.*=//: clobber left part before =
s/\./_/g: perform replacement of dots now that there's only right part in main buffer
H: append main buffer to hold buffer
x: swap buffers again
s/\n//: remove linefeed or both parts appear on separate lines
that was quite fun, but maybe sed is not the best tool to perform that operation, this rather belongs to code golf
I have a text file that takes the form of:
first thing: content 1
second thing: content 2
third thing: content 3
fourth thing: content 4
This pattern repeats throughout the entire text file. However, sometimes one of the rows is completely gone like so:
first thing: content 1
second thing: content 2
fourth thing: content 4
How could I search the document for these missing rows and just add it back with a value of "NA" or some filler to produce a new text file like this:
# 'third thing' was not there, so re-adding it with NA as content
first thing: content 1
second thing: content 2
third thing: NA
fourth thing: content 4
Current code boilerplate:
with open('original.txt, 'r') as in:
with open('output.txt', 'wb') as out:
#Search file for pattern (Maybe regex?)
#If pattern does not exist, add the line
Thanks for any help you all can offer!
You must look for 1-3 lines (less than 4) followed by newline:
^\n([^\n]*\n){1,3}\n
Demo: https://regex101.com/r/rL3eA5/2
This isn't pretty, but it works. Here's a regex to detect where lines are missing:
(?:^|\n)(second thing:\s*[^\n]+\n)|(first thing:\s*[^\n]+\n(?!second thing:))|(second thing:\s*[^\n]+\n(?!third thing:))|(third thing:\s*[^\n]+\n(?!fourth thing:))|(third thing:\s*[^\n]+\n\n)
regex101 demo here
Notice the Single Line flag.
When you've got a match, check which match group that matches. If it's the first one, the first line is missing. If it's the second one, the second line is missing and so on for third and fourth.
Here's an example how to replace if the 1'st group got a match.
Here's an example how to replace if the 3'rd group got a match.
Here's an example how to replace if the 4'rd group got a match.
You'll probably have to do some tweaking, but it should get you on your way ;)
Regards.
So few months ago one of my colleagues left. He used to comment all his code this way:
//----------------------------
// COMMENT
//----------------------------
private void func()...
So each comment, instead of using 1 line at most, uses 4 lines (including break line), which drives me crazy. I'm trying to create a Regex which I can remove this comment safely and replace it. The above code should like this way:
// COMMENT
private void func()...
I thought of just removing each one of the '//----------------------------' but it leaves me with many empty lines as well as break line between the comment and the actual line which to be described. Any help will be well appreciated.
EDIT
Note one:
Our project is written in Visual Studio
Note two: Some comments may contain more than 1 line of comment, example:
//----------------------------
// LINE 1 COMMENT
// LINE 2 COMMENT
//----------------------------
This expression matches your case and any 3 lines of comments where the first and the last ones have trailing -:
((\s|\t)*\/{2,})(.*[-]+)(\r?\n)((\1(.*)\4?)+)\4\1\3\4?
Try it here
And then you can replace it with:
\5 (or $5)
EDIT: for multi-line comments.
Here's a Regular Expression that you can use to strip out the excess (decorative) comment lines and convert these bulky comments into one-liners.
It also supports indentation and multi-line comments using this style:
//----------------------------
// LINE 1 COMMENT
// LINE 2 COMMENT
//----------------------------
private void func()...
Find:
(( |\t)*?\r\n)?( |\t)*?//-+(\r\n( |\t)*?// .+)+\r\n( |\t)*?//-+\r\n
Replace With:
\4
(Replace \4 with $4 if the replace failed)
Good luck!
I have a data file as follows.
1,14.23,1.71,2.43,15.6,127,2.8,3.06,.28,2.29,5.64,1.04,3.92,1065
1,13.2,1.78,2.14,11.2,100,2.65,2.76,.26,1.28,4.38,1.05,3.4,1050
1,13.16,2.36,2.67,18.6,101,2.8,3.24,.3,2.81,5.68,1.03,3.17,1185
1,14.37,1.95,2.5,16.8,113,3.85,3.49,.24,2.18,7.8,.86,3.45,1480
1,13.24,2.59,2.87,21,118,2.8,2.69,.39,1.82,4.32,1.04,2.93,735
Using vim, I want to reomve the 1's from each of the lines and append them to the end. The resultant file would look like this:
14.23,1.71,2.43,15.6,127,2.8,3.06,.28,2.29,5.64,1.04,3.92,1065,1
13.2,1.78,2.14,11.2,100,2.65,2.76,.26,1.28,4.38,1.05,3.4,1050,1
13.16,2.36,2.67,18.6,101,2.8,3.24,.3,2.81,5.68,1.03,3.17,1185,1
14.37,1.95,2.5,16.8,113,3.85,3.49,.24,2.18,7.8,.86,3.45,1480,1
13.24,2.59,2.87,21,118,2.8,2.69,.39,1.82,4.32,1.04,2.93,735,1
I was looking for an elegant way to do this.
Actually I tried it like
:%s/$/,/g
And then
:%s/$/^./g
But I could not make it to work.
EDIT : Well, actually I made one mistake in my question. In the data-file, the first character is not always 1, they are mixture of 1, 2 and 3. So, from all the answers from this questions, I came up with the solution --
:%s/^\([1-3]\),\(.*\)/\2,\1/g
and it is working now.
A regular expression that doesn't care which number, its digits, or separator you've used. That is, this would work for lines that have both 1 as their first number, or 114:
:%s/\([0-9]*\)\(.\)\(.*\)/\3\2\1/
Explanation:
:%s// - Substitute every line (%)
\(<something>\) - Extract and store to \n
[0-9]* - A number 0 or more times
. - Every char, in this case,
.* - Every char 0 or more times
\3\2\1 - Replace what is captured with \(\)
So: Cut up 1 , <the rest> to \1, \2 and \3 respectively, and reorder them.
This
:%s/^1,//
:%s/$/,1/
could be somewhat simpler to understand.
:%s/^1,\(.*\)/\1,1/
This will do the replacement on each line in the file. The \1 replaces everything captured by the (.*)
:%s/1,\(.*$\)/\1,1/gc
.........................
You could also solve this one using a macro. First, think about how to delete the 1, from the start of a line and append it to the end:
0 go the the start of the line
df, delete everything to and including the first ,
A,<ESC> append a comma to the end of the line
p paste the thing you deleted with df,
x delete the trailing comma
So, to sum it up, the following will convert a single line:
0df,A,<ESC>px
Now if you'd like to apply this set of modifications to all the lines, you will first need to record them:
qj start recording into the 'j' register
0df,A,<ESC>px convert a single line
j go to the next line
q stop recording
Finally, you can execute the macro anytime you want using #j, or convert your entire file with 99#j (using a higher number than 99 if you have more than 99 lines).
Here's the complete version:
qj0df,A,<ESC>pxjq99#j
This one might be easier to understand than the other solutions if you're not used to regular expressions!