How to get each function pattern in a file? - regex

I have a file contains a lot of functions, each function like
=======
CREATE PROCEDURE [fName]
code...
code...
END
GO
=======
I want to get every function pattern, and the expression I used is
^(CREATE PROCEDURE).*(\r\n.*)+\r\nGO
The result is wrong. Can somebady help! Thanks for answer

Using sed:
sed -n '/CREATE PROCEDURE/,/^END$/{H};/^GO$/{s/.*//;x;p;}' input

Try something more like:
(?<=^|\n)(CREATE PROCEDURE [\s\S]+?)(?=\r\nGO|$)
This will match every instance of CREATE PROCEDURE that starts a new line and the text that follows it, up to but not including the next GO directive, or the end of the file, whichever comes first.
In [\s\S]+?, the question mark makes this a non-greedy match, which is how we stop at the next GO instead of the last GO. [\s\S] is equivalent to [.\n], i.e., it matches any character.
I've assumed .NET-style regular expressions, since you didn't specify.

instead of using "." and \r\n try using [\s\S] it matches anything that is a whitespace OR isn't a whitespace including newlines.
CREATE PROCEDURE[\s\S]*GO
This may need some regex flags to be set

Related

Why does this regex fail to find matching pattern in string?

I have a file which will contain contents similar to the following example:
?[A7]DA<DA-SG
'[G7]G%SD\$DF
#[27]F:./4FFF
?[P9]W3_2SS_F
'[90]GA\\WTER
Each line ends in \r\n.
From this particular file, I need to replace the F:./4FFF part of the line #[27]F:./4FFF.
So far to start, I have this pattern in order to try and capture the part I need to replace:
\#\[27\]([\w\W]*)\r\n
The problem is that between the closing ] and the \r\n, could be any alphanumeric character or symbol.
I think the problem lies in the capturing group??? What is the correct pattern for this; I will be doing this in VBA.
You might be trying to design an expression, that would somewhat look like:
(?<=^#\[\d{2}\])\S*
DEMO 1
Or maybe just:
^(#\[\d+\])\S*
DEMO 2
Use the multiline option with these (regex.MULTILINE or something)
Two ways to do it
^#\[27\](.*)
or
^#\[27\]([^\r\n]*)
The thing is that \r\n is not needed to stop the match on the line.
It goes to the end without matching them.
This is advantageous if the line is the last one in the file.

Automatically slash the backslashes in vim

Can we write functions/subroutines in csh or vim?
Basically, my question is how to slash the backslashes inside a string automatically which we use for search in vim.
Lets say:
Contents of file file_a is:
abcd
a/b/c/d
Now, if I search 'abcd' inside vim with "/abcd" in command mode, it will match abcd(first line).
And If I search for 'a/b/c/d', it will not match whole of 'a/b/c/d'. It will match only 'a' from 'a/b/c/d'.
To match whole of 'a/b/c/d', I would need to search for a\/b\/c\/d. Slashing backslashes is a pain every time you want to search for strings having backslashes inside it. :)
Have anyone of you solved this earlier?
In Vim:
You can search backwards, where the separator is ? instead of /, so / does not need to be escaped: ?a/b/c/d; to move to the next match downwards, use N.
Or you can set the search pattern using :let #/="a/b/c/d" (this will not move the cursor), then use n to go the next match.
You can also define your own command:
function! FindSlashed(arg)
let #/=a:arg
norm n
endfunction
command! -nargs=1 S call FindSlashed(<q-args>)
which you can use like this:
:S a/b/c/d
EDIT: let, not set.
This is not about searching but about replacing. I thought you might find this helpful as you're writing functions
You can use alternate delimiters for replace command. ie, rather than using /, you can use something like #
:s#a/b/c/d#this text will replace#
The above command will replace a/b/c/d with this text will replace

Regular expression question

I have some text like this:
dagGeneralCodes$_ctl1$_ctl0
Some text
dagGeneralCodes$_ctl2$_ctl0
Some text
dagGeneralCodes$_ctl3$_ctl0
Some text
dagGeneralCodes$_ctl4$_ctl0
Some text
I want to create a regular expression that extracts the last occurrence of dagGeneralCodes$_ctl[number]$_ctl0 from the text above.
the result should be: dagGeneralCodes$_ctl4$_ctl0
Thanks in advance
Wael
This should do it:
.*(dagGeneralCodes\$_ctl\d\$_ctl0)
The .* at the front is greedy so initially it will grab the entire input string. It will then backtrack until it finds the last occurrence of the text you want.
Alternatively you can just find all the matches and keep the last one, which is what I'd suggest.
Also, specific advice will probably need to be given depending on what language you're doing this in. In Java, for example, you will need to use DOTALL mode to . matches newlines because ordinarily it doesn't. Other languages call this multiline mode. Javascript has a slightly different workaround for this and so on.
You can use:
[\d\D]*(dagGeneralCodes\$_ctl\d+\$_ctl0)
I'm using [\d\D] instead of . to make it match new-line as well. The * is used in a greedy way so that it will consume all but the last occurrence of dagGeneralCodes$_ctl[number]$_ctl0.
I really like using this Regular Expression Cheatsheet; it's free, a single page, and printed, fits on my cube wall.

Regex search and replace in VI

I have a document with lots of <swf...>.....</swf> in it. I would like to remove all these. Using vi when i type
:%s/\<swf[^\/swf>]+\/swf\>//g
I was hoping this would work, but it doesn't match anything.
You can remove all those from the buffer with this command:
:%s!<swf.\{-}/swf>!!
if you also have tags that might be split on two lines, you can add the \_ modifier to make . match newlines too:
:%s!<swf\_.\{-}/swf>!!
this assuming you want to remove both the tags and what they contain, if you just want to get rid of the tags and keep the content
:%s!</\?swf.\{-}>!!
Notes:
you don't need to escape < or >
you can choose whatever pattern delimiter you wish: Vim will use the first character you put after the s in the substitute command: this takes away the need to escape forward slashes in your pattern
EDIT: extending my answer after your comment
this is exactly like /STRING/REPLACE/g I only used a ! instead of / so that I don't have to quote the backslash in the pattern (see my second point above)
I didn't add the g modifier at the end since I have :set gdefault in my .vimrc since forever (it means that by default Vim will substitute all matches in a line instead of just the first, thus reverting the meaning of /g)
\{-} is the "ungreedy" version of the * quantifier, i.e. it matches 0 or more of the preceding atom but take as few as possible -- this helps you make sure that your search pattern will extend to the first "closing tag" instead of the last.
HTH
The problem here is that the [] is a character class, so you are telling it that between the swf opening and closing tags, the letters s, w and f cannot appear anywhere, in any order.
You could try a non-greedy match instead:
\<swf.\{-}\/swf\>
Note that . does not allow newline by default.
I don't use Vim though, so I used this guide to discover the syntax. I hope it is correct.

Match single character between Start string and End string

I can't seem to understand regular expression at all. How can I match a character which resides between a START and END string. For Example
#START-EDIT
#ValueA=0
#ValueB=1
#END-EDIT
I want to match any # which is between the #START-EDIT and #END-EDIT.
Specifically I want to use sed to replace the matches # values with nothing (delete them) on various files which may or may not have multiple START-EDIT and END-EDIT sections.
^#START-EDIT.*(#) *. *#END-EDIT$
sed is line based. you can easily search, replace based on regex in one line. But there is no really easy way to search/replace on multilines. AWK might do the trick.
If you have the regex on one line, the following command could be what you are looking for
sed -e "/^#START-EDIT.*#END-EDIT$//" myInput.txt