Receiving one set of numbers with regex - c#

I have info like the following
"id":"456138988365628440_103920","user"657852231654
and I would like to return,
456138988365628440_103920
I know using
"id":"[0-9_]*","user"
will return
"id":"456138988365628440_103920","user"
but I just want the id itself.

You can use capture groups by placing the part you want between parentheses and calling it back using match.Groups[1].Value:
string msg = #"""id"":""456138988365628440_103920"",""user""657852231654""";
var reg = new Regex(#"""id"":""([0-9_]*)"",""user""", RegexOptions.IgnoreCase);
var results = reg.Matches(msg);
foreach (Match match in results)
{
Console.WriteLine(match.Groups[1].Value);
}
ideone demo.

Or you could just use String.Split (if regex are not mandatory):
var input = #"""id"":""456138988365628440_103920"",""user""657852231654""";
var idValue = input.Split(',')[0].Split(':')[1];
Console.WriteLine(idValue);
Output:
456138988365628440_103920

What you need is a kind of conditional statement in your Regular Expression, which is called Zero-Width Positive Look-behind Assertion
In other words, you need a statement that says only match numbers which are after the id property.
"id":"456138988365628440_103920","user"657852231654
(?<="id":")[\d_]*
This regular expression would only return the requested number for you.
You can test it here.

Related

In Perl you use brackets to extract your matches what is the equivalent of that in c#

For instance in Perl I can do
$x=~/$(\d+)\s/ which is basically saying from variable x find any number preceded by $ sign and followed by any white space character. Now $1 is equal to the number.
In C# I tried
Regex regex = new Regex(#"$(\d+)\s");
if (regex.IsMatch(text))
{
// need to access matched number here?
}
First off, your regex there $(\d+)\s actually means: find a number after the end of the string. It can never match. You have to escape the $ since it's a metacharacter.
Anyway, the equivalent C# for this is:
var match = Regex.Match(text, #"\$(\d+)\s");
if (match.Success)
{
var number = match.Groups[1].Value;
// ...
}
And, for better maintainability, groups can be named:
var match = Regex.Match(text, #"\$(?<number>\d+)\s");
if (match.Success)
{
var number = match.Groups["number"].Value;
// ...
}
And in this particular case you don't even have to use groups in the first place:
var match = Regex.Match(text, #"(?<=\$)\d+(?=\s)");
if (match.Success)
{
var number = match.Value;
// ...
}
To get a matched result, use Match instead of IsMatch.
var regex = new Regex("^[^#]*#(?<domain>.*)$");
// accessible via
regex.Match("foo#domain.com").Groups["domain"]
// or use an index
regex.Match("foo#domain.com").Matches[0]
Use the Match method instead of IsMatch and you need to escape $ to match it literally because it is a character of special meaning meaning "end of string".
Match m = Regex.Match(s, #"\$(\d+)\s");
if (m.Success) {
Console.WriteLine(m.Groups[1].Value);
}

How can I capture value from capture function in C#

I have a problem when I want to capture the value using Capture function in C#.
My code looks for many patterns in a string, so I use match collection, then for each match I use Capture function. But when I want to replace the captureOut.value it does not work.
My code:
MatchCollection matches = Regex.Matches(string, #"\d*\.*\d+\s")
foreach (Match matchOut in matches)
{
foreach (Capture captureOut in matchOut.Captures)
Match match1 = Regex.Match(captureOut.Value, #"\d*\.*\d+");
::::: //}
output = Regex.Replace(output,captureOut.Value, Function1);
}
// i change the value of pattern based on the output of function 1
This part of my code, I do not know why capture out.value does not work.
Using the capture property only makes sense if you have groups in your regex, i.e. parts of your regex enclosed in ( ).
Since your regex has no, there is only one captured group and it's the whole string that matches the regex.

C# Regex match anything inside Parentheses

I want to match anything inside parentheses but the result must exclude the parentheses as well.
Examples:
Initialize(P90W)
Brake(45X)
Result:
990W
45X
note results without the Parentheses.
I've been trying to make this work but to no avail I tried a few variations but I know it's a simple thing I'm missing and I don't want to go using Replace to achieve it.
var item = "Brake(45X)"
Regex searchTerm = new Regex(#"\((.*)\)");
var value = (searchTerm.Match(item).Groups.Count > 0) ?
searchTerm.Match(item).Groups[0].Value : string.Empty;
Some people accuse me of using zero width assertions all the time:
resultString = Regex.Match(subjectString, #"(?<=\().+?(?=\))").Value;
But they do exactly what you want. Don't capture what you don't want to capture.
try regex #"\((.*?)\)"
EDIT: Also the result will be group 1 not 0, group 0 should contain the entire regex result, not the first parenthesized value
Remove the inner paranthesis and try again:
new Regex(#"(\([^\)]+\))");
When you do not escape paranthesis in regex, if you are using group match it will only return the content within the paranthesis. So if you have, new Regex(#'(a)(b))', match 1 will be a and match 2 will be b. Match 0 is the entire match.
Regex searchTerm = new Regex(#"\(([^\)]*)\)");
try this:
var pattern = #".*public.*(.*\(.*\))";
Regex.Matches(input,pattern)

question about regex

i'v got code
s = Regex.Match(item.Value, #"\/>.*?\*>", RegexOptions.IgnoreCase).Value;
it returns string like '/>test*>', i can replace symbols '/>' and '*>', but how can i return string without this symbols , only string 'test' between them?
You can save parts of the regex by putting ()'s around the area. so for your example:
// item.Value == "/>test*>"
Match m = Regex.Match(item.Value, #"\/>(.*?)\*>");
Console.WriteLine(m.Groups[0].Value); // prints the entire match, "/>test*>"
Console.WriteLine(m.Groups[1].Value); // prints the first saved group, "test*"
I also removed RegexOptions.IgnoreCase because we aren't dealing with any letters specifically, whats an uppercase /> look like? :)
You can group patterns inside the regx and get those from the match
var match= Regex.Match(item.Value, #"\/>(?<groupName>.*)?\*>", RegexOptions.IgnoreCase);
var data= match.Groups["groupName"].Value
You can also use look-ahead and look-behind. For your example it would be:
var value = Regex.Match(#"(?<=\/>).*?(?=\*>)").Value;

Determining which pattern matched using Regex.Matches

I'm writing a translator, not as any serious project, just for fun and to become a bit more familiar with regular expressions. From the code below I think you can work out where I'm going with this (cheezburger anyone?).
I'm using a dictionary which uses a list of regular expressions as the keys and the dictionary value is a List<string> which contains a further list of replacement values. If I'm going to do it this way, in order to work out what the substitute is, I obviously need to know what the key is, how can I work out which pattern triggered the match?
var dictionary = new Dictionary<string, List<string>>
{
{"(?!e)ight", new List<string>(){"ite"}},
{"(?!ues)tion", new List<string>(){"shun"}},
{"(?:god|allah|buddah?|diety)", new List<string>(){"ceiling cat"}},
..
}
var regex = "(" + String.Join(")|(", dictionary.Keys.ToArray()) + ")";
foreach (Match metamatch in Regex.Matches(input
, regex
, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture))
{
substitute = GetRandomReplacement(dictionary[ ????? ]);
input = input.Replace(metamatch.Value, substitute);
}
Is what I'm attempting possible, or is there a better way to achieve this insanity?
You can name each capture group in a regular expression and then query the value of each named group in your match. This should allow you to do what you want.
For example, using the regular expression below,
(?<Group1>(?!e))ight
you can then extract the group matches from your match result:
match.Groups["Group1"].Captures
You've got another problem. Check this out:
string s = #"My weight is slight.";
Regex r = new Regex(#"(?<!e)ight\b");
foreach (Match m in r.Matches(s))
{
s = s.Replace(m.Value, "ite");
}
Console.WriteLine(s);
output:
My weite is slite.
String.Replace is a global operation, so even though weight doesn't match the regex, it gets changed anyway when slight is found. You need to do the match, lookup, and replace at the same time; Regex.Replace(String, MatchEvaluator) will let you do that.
Using named groups like Jeff says is the most robust way.
You can also access the groups by number, as they are expressed in your pattern.
(first)|(second)
can be accessed with
match.Groups[1] // match group 2 -> second
Of course if you have more parenthesis which you don't want to include, use the non-capture operator ?:
((?:f|F)irst)|((?:s|S)econd)
match.Groups[1].Value // also match group 2 -> second

Categories

Resources