Using an escape character with a beginning wildcard in regex in c# - c#

Below is a sample of an email I am using from a database:
2.2|[johnnyappleseed#example.com]
Every line is different, and it may or may not be an email, but it will always. I am trying to use regular expressions to get the information inside the brackets. Below is what I have been trying to use:
^\[\]$
Unfortunately, every time I try to use it, the expression isn't matching. I think the problem is using the escape characters, but I am not sure. If this is not how I use the escape characters with this, or if I am wrong completely, please let me know what the actual regex should be.

Close to yours is ^.*\[(.*)\]$:
^ start of the line
.* anything
\[ a bracket, indicating the start of the email
(.*) anything (the email), as a capturing group
\] a square bracked, indicating the end of the email
$ end of the line
Note that your Regex is missing the .* parts to match the things between the key characters [ and ].

Your regex - ^\[\]$ - matches a single string/line that only contains [], and you need to obtain a substring inbetween the square brackets somewhere further inside a larger string.
You can use
var rx = new Regex(#"(?<=\[)[^]]+");
Console.WriteLine(rx.Match(s).Value);
See regex demo
With (?<=\[) we find the position after [ and then we match every character that is not ] with [^]]+.
Another, non-regex way:
var s = "2.2|[johnnyappleseed#example.com]";
var ss = s.Split('|');
if (ss.GetLength(0) > 1)
{
var last = ss[ss.GetLength(0)-1];
if (last.Contains("[") && last.Contains("#")) // We assume there is an email
Console.WriteLine(last.Trim(new[] {'[', ']'}));
}
See IDEONE demo of both approaches

Related

Remove some specific string with special character

Input String
string b = "14-03-002980 AND 14-03- [ ] (5)Description of 002981";
In output String I Want Result As
4-03-002980 AND 14-03-002981
I tried with below regex but it, not works
Regex.Replace(b, "[#&'(\\s)<>(5)Description of ]","");
Plaese, help me if anyone knows how to do this thing.
You can use this regex,
\s+\[.*(?=\b\d+)
and replace it with empty string.
You start with one or more whitespace then match a [ using \[ and then .* consumes all the characters greedily and only stops when it sees a number using positive look ahead (?=\b\d+)
Regex Demo

Star - look for the character * in a string using regex

I am trying to find the following text in my string : '***'
the thing is that the C# Regex mechanism doesnt allow me to do the following:
new Regex("***", RegexOptions.CultureInvariant | RegexOptions.Compiled);
due to
ArgumentException: "parsing "*" - Quantifier {x,y} following nothing."
obviously it thinks that my stars represents regular expressions,
is there a way to tell the Regex mechanism to treat stars as just stars and nothing else?
* in Regex means:
Matches the previous element zero or more times.
so that, you need to use \* or [*] instead.
explain:
\
When followed by a character that is not recognized as an escaped character in this and other tables in this topic, matches that character. For example, \* is the same as \x2A.
[ character_group ]
Matches any single character in character_group.
You need to escape the star with a backslash: #"\*"

Fetch values between two [] from a string using Regular expressions

I have a string like as folows :
"channel_changes":[[1313571300,26.879846,true],[1313571360,26.901025,true]]
I want to extract each string in angular brace like 1313571300, 26.879846, true
through regular expression.
I have tried using
string regexPattern = #"\[(.*?)\]";
but that gives the first string as [[1313571420,26.901025,true]
i.e with one extra angular brace.
Please help me how can I achieve this.
This seemed to work in Expresso for me:
\[([\w,\.]*?)\]
Literal [
[1]: A numbered capture group. [[\w,.]*?]
- Any character in this class: [\w,.], any number of repetitions, as few as possible
Literal ]
The problem seemed to be the "." in your regex - since it was picking up the first literal "[" and considering the following "[" in your input to be valid as the next character.
I constrained it to just alphanumeric characters, commas and literal full-stops (period mark), since that's all that was present in your example. You could go further and really specify the format of the data inside those inner square brackets assuming it's consistent, and end up with something more like this:
\[[0-9.]+,[0-9.]+,(true|false)\]
Example C# code:
var matches = Regex.Matches("\"channel_changes\":[[1313571300,26.879846,true],[1313571360,26.901025,true]]", #"\[([\w,\.]*?)\]");
foreach (var match in matches)
{
Console.WriteLine(match);
}
Try this:
#"\[+([^\]]+)\]+"
"[^]]+" - it means any character except right square bracket
Try this
\[([^\[\]]*)\]
See it here online on Regexr
[^\[\]]* is a negated character class, means match any character but [ and ]. With this construct you don't need the ? to make your * ungreedy.

Regex battle between maximum and minimum munge

Greetings, I have file with the following strings:
string.Format("{0},{1}", "Having \"Two\" On The Same Line".Localize(), "Is Tricky For regex".Localize());
my goal is to get a match set with the two strings:
Having \"Two\" On The Same Line
Is Tricky For regex
My current regex looks like this:
private Regex CSharpShortRegex = new Regex("\"(?<constant>[^\"]+?)\".Localize\\(\\)");
My problem is with the escaped quotes in the first line I end up stopping at the quote and I get:
On The Same Line
Is Tricky For This Style Too
however attempting to ignore the escaped quotes is not working out because it makes the Regex greedy and I get
Having \"Two\" On The Same Line".Localize(), "Is Tricky For regex"
We seem to be caught between maximum and minimum munge. Is there any hope? I have some backup plans. Can you Regex backwards? that would make it easier because I can start with the "()ezilacoL."
EDIT:
To clarify. This is my lone edge case. Most of the time the string sits alone like:
var myString = "Hot Patootie".Localize()
This one works for me:
\"((?:[^\\"]|(?:\\\"))*)\"\.Localize\(\)
Tested on http://www.regexplanet.com/simple/index.html against a number of strings with various escaped quotes.
Looks like most of us who answered this one had the same rough idea, so let me explain the approach (comments after #s):
\" # We're looking for a string delimited by quotation marks
( # Capture the contents of the quotation marks
(?: # Start a non-capturing group
[^\\"] # Either read a character that isn't a quote or a slash
|(?:\\\") # Or read in a slash followed by a quote.
)* # Keep reading
) # End the capturing group
\" # The string literal ends in a quotation mark
\.Localize\(\) # and ends with the literal '.Localize()', escaping ., ( and )
For C# you'll need to escape the slashes twice (messy):
\"((?:[^\\\\\"]|(?:\\\\\"))*)\"\\.Localize\\(\\)
Mark correctly points out that this one doesn't match escaped characters other than quotation marks. So here's a better version:
\"((?:[^\\"]|(?:\\")|(?:\\.))*)\"\.Localize\(\)
And its slashed-up equivalent:
\"((?:[^\\\\\"]|(?:\\\\\")|(?:\\\\.))*)\"\\.Localize\\(\\)
Works the same way, except it has a special case that if encounters a slash but it can't match \", it just consumes the slash and the following character and moves on.
Thinking about it, it's better to just consume two characters at every slash, which is effectively Mark's answer so I won't repeat it.
Here's the regular expression you need:
#"""(?<constant>(\\.|[^""])*)""\.Localize\(\)"
A test program:
using System;
using System.Text.RegularExpressions;
using System.IO;
class Program
{
static void Main()
{
Regex CSharpShortRegex =
new Regex(#"""(?<constant>(\\.|[^""])*)""\.Localize\(\)");
foreach (string line in File.ReadAllLines("input.txt"))
foreach (Match match in CSharpShortRegex.Matches(line))
Console.WriteLine(match.Groups["constant"].Value);
}
}
Output:
Having \"Two\" On The Same Line
Is Tricky For regex
Hot Patootie
Notice that I have used #"..." to avoid having to escape backslashes inside the regular expression. I think this makes it easier to read.
Update:
My original answer (below the horizontal rule) has a bug: regular-expression matchers attempt alternatives in left-to-right order. Having [^"] as the first alternative allows it to consume the backslash, but then the next character to be matched is a quote, which prevents the match from proceeding.
Incompatibility note: Given the pattern below, perl backtracks to the other alternative (the escaped quote) and successfully finds a match for the Having \"Two\" On The Same Line case.
The fix is to try an escaped quote first and then a non-quote:
var CSharpShortRegex =
new Regex("\"(?<constant>(\\\\\"|[^\"])*)\"\\.Localize\\(\\)");
or if you prefer the at-string form:
var CSharpShortRegex =
new Regex(#"""(?<constant>(\\""|[^""])*)""\.Localize\(\)");
Allow for escapes:
private Regex CSharpShortRegex =
new Regex("\"(?<constant>([^\"]|\\\\\")*)\"\\.Localize\\(\\)");
Applying one level of escaping to make the pattern easier to read, we get
"(?<constant>([^"]|\\")*)"\.Localize\(\)
That is, a string starts and ends with " characters, and everything between is either a non-quote or an escaped quote.
Looks like you're trying to parse code so one approach might be to evaluate the code on the fly:
var cr = new CSharpCodeProvider().CompileAssemblyFromSource(
new CompilerParameters { GenerateInMemory = true },
"class x { public static string e() { return " + input + "}}");
var result = cr.CompiledAssembly.GetType("x")
.GetMethod("e").Invoke(null, null) as string;
This way you could handle all kinds of other special cases (e.g. concatenated or verbatim strings) that would be extremely difficult to handle with regex.
new Regex(#"((([^#]|^|\n)""(?<constant>((\\.)|[^""])*)"")|(#""(?<constant>(""""|[^""])*)""))\s*\.\s*Localize\s*\(\s*\)", RegexOptions.Compiled);
takes care of both simple and #"" strings. It also takes into account escape sequences.

Matching an (easy??) regular expression using C#'s regex

Ok sorry this might seem like a dumb question but I cannot figure this thing out :
I am trying to parse a string and simply want to check whether it only contains the following characters : '0123456789dD+ '
I have tried many things but just can't get to figure out the right regex to use!
Regex oReg = new Regex(#"[\d dD+]+");
oReg.IsMatch("e4");
will return true even though e is not allowed...
I've tried many strings, including Regex("[1234567890 dD+]+")...
It always works on Regex Pal but not in C#...
Please advise and again i apologize this seems like a very silly question
Try this:
#"^[0-9dD+ ]+$"
The ^ and $ at the beginning and end signify the beginning and end of the input string respectively. Thus between the beginning and then end only the stated characters are allowed. In your example, the regex matches if the string contains one of the characters even if it contains other characters as well.
#comments: Thanks, I fixed the missing + and space.
Oops, you forgot the boundaries, try:
Regex oReg = new Regex(#"^[0-9dD +]+$");
oReg.IsMatch("e4");
^ matches the begining of the text stream, $ matches the end.
It is matching the 4; you need ^ and $ to terminate the regex if you want a full match for the entire string - i.e.
Regex re = new Regex(#"^[\d dD+]+$");
Console.WriteLine(re.IsMatch("e4"));
Console.WriteLine(re.IsMatch("4"));
This is because regular expressions can also match parts of the input, in this case it just matches the "4" of "e4". If you want to match a whole line, you have to surround the regex with "^" (matches line start) and "$" (matches line end).
So to make your example work, you have to write is as follows:
Regex oReg = new Regex(#"^[\d dD+]+$");
oReg.IsMatch("e4");
I believe it's returning True because it's finding the 4. Nothing in the regex excludes the letter e from the results.
Another option is to invert everything, so it matches on characters you don't want to allow:
Regex oReg = new Regex(#"[^0-9dD+]");
!oReg.IsMatch("e4");

Categories