Replacing multiple string Replace() with a single Regex.Replace() - regex

if I'm doing something like that:
someString.Replace("abc","").Replace("def","").Replace(#"c:\Windows","")
How can I replace that with
Regex.Replace(someString," \\here I don't know what the pattern should be")
I've tried this:
Regex.Replace(someString, #"(?:abc|def|c:\Windows)")
but it didn't work
UPD...
The problem is when I pass the path like that
Regex.Replace(someString, #"(?:abc|def|"+aPath+")")

`But it didnt work` doesn't say much helpfull!
Try this:
someString = Regex.Replace(someString, #"(?:abc|def|ghi|c:\\Windows)", "")
It did work when I tried it. I thinks the reason why your code doesn't work is because you forgot the replacement string and you have to escape the backslash in the path.

I'm assuming the thing that "didn't work" is your C:\windows replacement. You need
someString = Regex.Replace(someString, #"(?:abc|def|C:\\windows)","");
The problem is you need to escape your backslash. An unescaped backslash has meaning in regex. In particular, in this case, \W actually matches any non-alphanumeric character.
Edit to escape an any arbitrary string, you can use Regex.Escape(yourString);

Related

How do I only find newlines in a Regex?

I have a regex which finds newlines encoded in strings as \n (not the actual newline character), but it also finds encoded escaped newlines (\\n), like before the word "anything" in the string below.
var rg = '/(\\n)/g'
var str = 'so you can do pretty much \\nanything you want with it. \n\nAt runtime Carota has'
How can I find all of the newlines and none of the escaped newlines?
Here is a link with an example. https://regexr.com/4fna7
You probably want a negative lookbehind. This is used to look for characters behind text, but not include it in the capture.
Your rewritten regex would look like:
(?<!\\)(\\n)
One way to do this is to begin with a negated character class to ensure you do not pick up the double backslash:
var rg = '/[^\\](\\n)/g'
var str = 'so you can do pretty much \\nanything you want with it. \n\nAt runtime Carota has'
I'm assuming you're using JavaScript. In which case you can simply use the Regex literals like so:
/\n/
That would match all newline characters. If you can't use a Regex literal, JS also offers a constructor which takes a string
new RegExp('\\n')
In order to match the \\n you will need to escape the backslash:
/\\n|\n/
with constructor:
new RegExp('\\\\n|\\n')
Hope that helps.

Trouble converting regex

This regex:
"REGION\\((.*?)\\)(.*?)END_REGION\\((.*?)\\)"
currently finds this info:
REGION(Test) my user typed this
END_REGION(Test)
I need it to instead find this info:
#region REGION my user typed this
#endregion END_REGION
I have tried:
"#region\\ (.*?)\\\n(.*?)#endregion\\ (.*?)\\\n"
It tells me that the pattern assignment has failed. Can someone please explain what I am doing wrong? I am new to Regex.
It seems the issue lies in the multiline \n. My recommendation is to use the modifier s to avoid multiline complexities like:
/#region\ \(.*?\)(.*?)\s#endregion\s\(.*?\)/s
Online Demo
s modifier "single line" makes the . to match all characters, including line breaks.
Try this:
#region(.*)?\n(.*)?#endregion(.*)?
This works for me when testing here: http://regexpal.com/
When using your original text and regex, the only thing that threw it off is that I did not have a new line at the end because your sample text didn't have one.
Constructing this regex doesn't fail using boost, even if you use the expanded modifier.
Your string to the compiler:
"#region\\ (.*?)\\\n(.*?)#endregion\\ (.*?)\\\n"
After parsed by compiler:
#region\ (.*?)\\n(.*?)#endregion\ (.*?)\\n
It looks like you have one too many escapes on the newline.
if you present the regex as expanded to boost, an un-escaped pound sign # is interpreted as a comment.
In that case, you need to escape the pound sign.
\#region\ (.*?)\\n(.*?)\#endregion\ (.*?)\\n
If you don't use the expanded modifier, then you don't need to escape the space characters.
Taking that tack, you can remove the escape on the space's, and fixing up the newline escapes, it looks like this raw (what gets passed to regex engine):
#region (.*?)\n(.*?)#endregion (.*?)\n
And like this as a source code string:
"#region (.*?)\\n(.*?)#endregion (.*?)\\n"
Your regular expression has an extra backslash when escaping the newline sequence \\\n, use \\s* instead. Also for the last capturing group you can use a greedy quantifier instead and remove the newline sequence.
#region\\ (.*?)\\s*(.*?)#endregion\\ (.*)
Compiled Demo

RegEx for quoted string with missing open parenthesis

What is RegEx for find quoted string having only close parenthesis at the end, like this :
"People)"
But not
"(People)"
Something like so: "[^(]+?\)" should fit the bill. You might also need to escape the quotation marks and the backslash as well, depending on what regex engine you are using.
Some details on how does this regex work are available here.
Can you try the following ?
String REGEX_TEST_STRING="\"People)\"";
System.out.println(REGEX_TEST_STRING.matches("\"P.*\)\""));
This code returns true for "People)" and false for "(People)"
HTH.

How do I need to escape search string in vim?

I need to search and replace this:
ExecIf($["${debug}" = "1"]?NoOp
with this:
GoSub(chanlog,s,1(1,[${CHANNEL}]
I can't seem to do it in vim, and I'm not sure what needs to be escaped, as nothing I've tried works.
If you want to change a long string with lots of punctuation characters, and it's an exact match (you don't want any of them to be treated as regex syntax) you can use the nomagic option, to have the search pattern interpreted as a literal string.
:set nomagic
:%s/ExecIf($["${debug}" = "1"]?NoOp/GoSub(chanlog,s,1(1,[${CHANNEL}]/
:set magic
You still have to watch out for the delimiters (the slashes of the s/// command) but you can use any character for that, it doesn't have to be a slash, so when you have something like this and there are slashes in the search or replace string, just pick something else, like s#foo#bar# or s:bar:baz:.
If you're having problems with which characters to escape in a vim substitution (:s//), remember the nomagic concept, and in particular the nomagic version of a substitute: :snomagic// or :sno//. nomagic means: interpret each character literally.
So this should work without worrying about escaping characters in the substitution:
:sno/ExecIf($["${debug}" = "1"]?NoOp/GoSub(chanlog,s,1(1, [${CHANNEL}]/
Get to know magic vs. nomagic, :sno//, and \v, \V:
:help magic
The nomagic version of a search for your string uses \V:
/\VExecIf($["${debug}" = "1"]?NoOp
you have to escape the [] and the spaces:
:s/ExecIf($\["${debug}"\ =\ "1"\]?NoOp/GoSub(chanlog,s,1(1,\[${CHANNEL}\]/
just a bit trial and error

Regex - Multiline Problem

I think I'm burnt out, and that's why I can't see an obvious mistake. Anyway, I want the following regex:
#BIZ[.\s]*#ENDBIZ
to grab me the #BIZ tag, #ENDBIZ tag and all the text in between the tags. For example, if given some text, I want the expression to match:
#BIZ
some text some test
more text
maybe some code
#ENDBIZ
At the moment, the regex matches nothing. What did I do wrong?
ADDITIONAL DETAILS
I'm doing the following in PHP
preg_replace('/#BIZ[.\s]*#ENDBIZ/', 'my new text', $strMultiplelines);
The dot loses its special meaning inside a character class — in other words, [.\s] means "match period or whitespace". I believe what you want is [\s\S], "match whitespace or non-whitespace".
preg_replace('/#BIZ[\s\S]*#ENDBIZ/', 'my new text', $strMultiplelines);
Edit: A bit about the dot and character classes:
By default, the dot does not match newlines. Most (all?) regex implementations have a way to specify that it match newlines as well, but it differs by implementation. The only way to match (really) any character in a compatible way is to pair a shorthand class with its negation — [\s\S], [\w\W], or [\d\D]. In my personal experience, the first seems to be most common, probably because this is used when you need to match newlines, and including \s makes it clear that you're doing so.
Also, the dot isn't the only special character which loses its meaning in character classes. In fact, the only characters which are special in character classes are ^, -, \, and ]. Check out the "Metacharacters Inside Character Classes" section of the character classes page on Regular-Expressions.info.
// Replaces all of your code with "my new text", but I do not think
// this is actually what you want based on your description.
preg_replace('/#BIZ(.+?)#ENDBIZ/s', 'my new text', $contents);
// Actually "gets" the text, which is what I think you might be looking for.
preg_match('/(#BIZ)(.+?)(#ENDBIZ)/s', $contents, $matches);
list($dummy, $startTag, $data, $endTag) = $matches;
This should work
#BIZ[\s\S]*#ENDBIZ
You can try this online Regular Expression Testing Tool
The mistake is the character group [.\s] that will match a dot (not any character) or white space. You probably tried to get .* with . matching newline characters, too. You achieve this by enabling the single line option ((?s:) does this in .NET regex).
(?s:#BIZ.*?#ENDBIZ)
Depending on the environment you're using your regex in, it may need special care to properly parse multiline text, eg re.DOTALL in Python. So what environment is that?
you can use
preg_replace('/#BIZ.*?#ENDBIZ/s', 'my new text', $strMultiplelines);
the 's' modifier says "match the dot with anything, even the newline character". the '?' says don't be greedy, such as for the case of:
foo
#BIZ
some text some test
more text
maybe some code
#ENDBIZ
bar
#BIZ
some text some test
more text
maybe some code
#ENDBIZ
hello world
the non-greediness won't get rid of the "bar" in the middle.
Unless I am missing something, you handle this the same way that you would in Perl, with either the /m or /s modifier at the end? Oddly enough the other answers that rather correctly pointed this out got down voted?!
It looks like you're doing a javascript regex, you'll need to enable multiline by specifying the m flag at the end of the expression:
var re = /^deal$/mg