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)
Related
I have posted this earlier but did not give clear information on what i was trying to achieve.
I am trying get values from a string using Regex in c#. I am not able to understand why some values i could get and some i can not using a similar approach.
Please find the code snippet below.
Kindly let me know what i am missing.
Thanks in advance.
string text = "0*MAO-001*20160409*20160408*Encounter Data Duplicates Report * *ENC000200800400120160407*PRO*PROD*";
//toget the value 20160409 from the above text
//this code works fine
Regex pattern = new Regex(#"([0][*]MAO[-][0][0][1].*?[*](?<Value>\d+)[*])");
Match match = pattern.Match(text);
string Value = match.Groups["Value"].Value.ToString();
//to get the value ENC000200800400120160407 from the above text
// this does not work and gives me nothing
Regex pattern2 = new Regex(#"([0][*]MAO[-][0][0][1].*?[*].*?[*].*?[*].*?[*].*?[*](?<Value2>\d+)[*])");
Match match2 = pattern.Match(text);
string Value2 = match.Groups["Value2"].Value.ToString();
It looks your file is '*' delimitered.
You can use one single regex to catch all the values
Try use
((?<values>[^\*]+)\*)
as your pattern.
All these values will be catched in values array.
----Update add c# code-----
string text = "0*MAO-001*20160409*20160408*Encounter Data Duplicates Report * *ENC000200800400120160407*PRO*PROD*";
Regex pattern = new Regex(#"(?<values>[^\*]+)\*");
var matches = pattern.Matches(text);
string Value = matches[3].Groups["values"].Captures[0];
string Value2 = matches[6].Groups["values"].Captures[0];
You need to use this for 2nd regex
([0][*]MAO[-][0][0][1].*?[*].*?[*].*?[*].*?[*].*?[*](?<Value2>\w+)[*])
\w is any character from set [A-Za-z0-9_]. You were using only \d which searches for digits [0-9] which was not the case
C# Code
In your second try at using the regex, you are matching with pattern and not pattern2.
Match match2 = pattern.Match(text);
string Value2 = match.Groups["Value2"].Value.ToString();
You are also using the Groups from match and not match2.
This is why it is important to name your variables something meaningful to what they represent. Yes it may be a "pattern" but what does that pattern represent. When you use variables that are vaguely named it creates issues like these.
You almost got it, but the field you're looking for contains letters and digits.
This is your second regex kind of fixed.
([0][*]MAO[-][0][0][1].*?[*](?:.*?[*]){4}(?<Value2>.*?)[*])
( # (1 start)
[0] [*] MAO [-] [0] [0] [1] .*? [*]
(?: .*? [*] ){4}
(?<Value2> .*? ) # (2)
[*]
) # (1 end)
To make it a little less busy, this might be better
(0\*MAO-001.*?\*(?:[^*]*\*){4}(?<Value2>[^*]*)\*)
I tried to find a method to count a specific word in a string, and I found this.
using System.Text.RegularExpressions;
MatchCollection matches = Regex.Matches("hi, hi, everybody.", ",");
int cnt = matches.Count;
Console.WriteLine(cnt);
It worked fine, and the result shows 2.
But when I change "," to ".", it shows 18, not the expected 1. Why?
MatchCollection matches = Regex.Matches("hi, hi, everybody.", ".");
and when I change "," to "(", it shows me an error!
the error reads:
SYSTEM.ARGUMENTEXCEPTION - THERE ARE TOO MANY (...
I don't understand why this is happening
MatchCollection matches = Regex.Matches("hi( hi( everybody.", "(");
Other cases seem to work fine but I need to count "(".
The first instance, with the ., is using a special character which has a different meaning in regular expressions. It is matching ALL of the characters you have; hence you getting a result of 18.
http://www.regular-expressions.info/dot.html
To match an actual "." character, you'll need to "escape" it so that it is read as a full-stop and not a special character.
MatchCollection matches = Regex.Matches("hi, hi, everybody.", "\.");
The same exists for the ( character. It's a special character that has a different meaning in terms of regular expressions and you will need to escape it.
MatchCollection matches = Regex.Matches("hi( hi( everybody.", "\(");
Looks like you're new to regular expressions so I'd suggest reading, the link I posted above is a good start.
HOWEVER!
If you are looking to just count ocurences in a string, you don't need regex.
How would you count occurrences of a string within a string?
If you're using .NET 3.5 you can do this in a one-liner with LINQ:
int cnt = source.Count(f => f == '(');
If you don't want to use LINQ you can do it with:
int cnt = source.Split('(').Length - 1;
The second parameter represents a pattern, not necessarily just a character to search for in your string, and the ( by itself is an invalid pattern.
You don't need Regex to count occurrences of a character. Just use LINQ's Count():
var input = "hi( hi( everybody.";
var occurrences = input.Count(x => x == '('); // 2
( character is a special character which means start of a group. If you need to use ( as literal you need to escape it with \(. That should solve your problem.
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.
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;
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