Retrieve array from string with regular expression in C# - c#

I have following string:
"option1,option2->data1,data2,data3,..."
I'm learning C# and also regular expressions, so I thought I might have some fun with it, but I can't figure out how to get an array from this.
For example, I'd like to retrieve array of strings that looks like this one:
[option1,option2,data1,data2,data3,...]
Here's regular expression I wrote in regex tester (.+),(.+)->((.+),?), but I'm not sure if this will work. And also I don't know how to use regex functions in C# to achieve this. I guess I should use something from System.Text.RegularExpressions but I'm not really sure what.
Long story short:
I want to get array from string using regular expressions.
"option1,option2->data1,data2,..." -> [option1,option2,data1,data2,...]
Thanks!

I would avoid RegularExpressions for this. you can simply do this:
string[] myArray = inputString.Replace("->", ",").Split(',');

It seems like you need direction more than an answer.
http://www.RegexHero.com is a good place to test your regex against strings.
http://www.mikesdotnetting.com/Article/46/CSharp-Regular-Expressions-Cheat-Sheet is a cheat sheet/guide for c# regex
http://www.dotnetperls.com/regex-match here's a good place to start with regex in c#

You haven't posed anything that string.Split can't handle:
var split = given.Split(new [] {",", "->"}, StringSplitOptions.None);

Related

Correct wrong occurrences in a string

Buggy control provides in text something like this:
{{\field{\*\fldinst{HYPERLINK http://yandex.ru }}{\fldrslt{http://yandex.ru\ul0\cf0}}}}\f0\fs24
but correct version is:
{{\field{\*\fldinst{HYPERLINK http://yandex.ru }}{\fldrslt{\ul\cf1 http://yandex.ru}}}}\f0\fs24
I'm really newbie in regex and other text tools, so I don't know how replace all occurrences with correct variant in righteous way. We can't rewrite control logic now, there is more WinAPI code.
Platform is .NET Framework 2.0
Well, basically regular expression you've generated is ok, as it does in job and find all occurences like {http://yandex.com\ul0\cf0}.
If I have understood your goal correctly - the only transformation you need in each capture group - is transform {http://yandex.com\ul0\cf0} to {\ul\cf1 http://yandex.com}.
This can be done easily with Regex.Replace override having MatchEvaluator as argument.
For example, something like this (note, it is not most elegant solution, rather it is "quick and dirty"):
var result = Regex.Replace(source_Text, regex_pattern,
x => x.Groups[0].Value.Replace(#"\ul0\cf0", "").Replace("{", #"{\ul\cf1 "));

How do I do the following using only regex?

Say I have the following string
[id={somecomplexuniquestring}test1],
[id={somecomplexuniquestring}test2],[id={somecomplexuniquestring}test3],
[id={somecomplexuniquestring}test4],[id={somecomplexuniquestring}test5],
[id={somecomplexuniquestring}test6],[id={somecomplexuniquestring}test7],
[id={somecomplexuniquestring}test8],[id={somecomplexuniquestring}test9]
is there a way just using regex to get the following result [id={somecomplexuniquestring}test6]
{somecomplexuniquestring} are unknown strings which cannot be used in the regex.
For example, the following will not work #"[id=[\s\S]+?test6]" as it starts from the very first id.
Is using RegEx the best solution? You have tagged C#, so would
variableWithString.Split(",").Any(x => x.Contains("test6"));
give you the exists match, or
result = variableWithString.Split(",").Where(x => x.Contains("test6"));
give you the match value you are seeking?
This doesn't work??
\[id={.*?}test6\]
This all depends on exactly what the limitations of somecomplexuniquestring are. For example, if you have a guarantee that they do not contain any [ or ] characters, you can use this simple one:
"\[[^\[\]]*test6\]"
Similarly, if it could contain square brackets but no curly braces, you can do something similar:
"\[id={[^{}]*}test6\]"
HOWEVER, if you have no such guarantee, and there's some sort of escaping system for including {} or [] in that string, then you need to let us know how that works to properly answer.
You can use this pattern:
#"\[[^]]*]"
If you want a specific test number you can do this:
#"\[id={[^}]*}test6]"

Equivalent of Substring as a RegularExpression

Ok, I need a general regular expression that will give me the x characters from a string starting at position y like the string's substring function:
input_str.Substring(y,x)
But as a C# regular expression.
Example:
1234567890 Substring(5,3) 678
I know you are thinking why not just use the Substring function? The short answer is because this goes as a data for an existing function and in this context it would be inelegant to create a whole separate data parsing mechanism. We'd like to get this working without changing the code.
I feel like this is really obvious--but I'm pretty inexperienced with regular expressions. Thanks in advance for any help.
.{y}(.{x}).* should do it, I think, then just pull out the capture group.

RegEx replace with calculations?

Is it possible somehow to do a RegEx-replace with a calculation in the result? (in VS2010)
Such as:
Grid\.Row\=\"{[0-9]+}\"
to
Grid.Row="eval(int(\1) + 1)"
You can use a MatchEvaluator do achieve this, like
String s = Regex.Replace("1239", #"\d", m => (Int32.Parse(m.ToString()) + 1).ToString());
Output: 23410
Edit:
I just noticed... if you mean "using the VS2010 find-replace feature" and not "using C#", then the answer is "no", i am afraid.
You could always use capturing to retrieve any values you need for your calculation and then perform a RegEx Replace with a new RegEx that's constructed from you're equation and any values you captured.
If the equation doesn't use anything from the input text, one RegEx would be sufficient. You'd simply construct it by concatenating the static portions together with the computed value(s).
Unfortunately, C# and .NET do not provide an eval method or equivalent. However, it is possible to either use a library for expression parsing (a quick google gave me this .NET Math Expression Parser) or write your own (which is actually pretty easy, check out the Shunting-yard Algorithm and Postfix Notation). Simply capture the group then output the group value to the library/method you have written.
Edit: I see now you want this for the VS2010 program. This is unachievable unless you write your own VS extension. You could always write a program to search and replace your code and feed the code into it, then replace it the original code with its output.

Conditional Regex Replace in C# without MatchEvaluator

So, Im trying to make a program to rename some files. For the most part, I want them to look like this,
[Testing]StupidName - 2[720p].mkv
But, I would like to be able to change the format, if so desired. If I use MatchEvaluators, you would have to recompile every time. Thats why I don't want to use the MatchEvaluator.
The problem I have is that I don't know how, or if its possible, to tell Replace that if a group was found, include this string. The only syntax for this I have ever seen was something like (?<group>:data), but I can't get this to work. Well if anyone has an idea, im all for it.
EDIT:
Current Capture Regexes =
^(\[(?<FanSub>[^\]\)\}]+)\])?[. _]*(?<SeriesTitle>[\w. ]*?)[. _]*\-[. _]*(?<EpisodeNumber>\d+)[. _]*(\-[. _]*(?<EpisodeName>[\w. ]*?)[. _]*)?([\[\(\{](?<MiscInfo>[^\]\)\}]*)[\]\)\}][. _]*)*[\w. ]*(?<Extension>\.[a-zA-Z]+)$
^(?<SeriesTitle>[\w. ]*?)[. _]*[Ss](?<SeasonNumber>\d+)[Ee](?<EpisodeNumber>\d+).*?(?<Extension>\.[a-zA-Z]+)$
^(?<SeriesTitle>[\w. ]*?)[. _]*(?<SeasonNumber>\d)(?<EpisodeNumber>\d{2}).*?(?<Extension>\.[a-zA-Z]+)$
Current Replace Regex = [${FanSub}]${SeriesTitle} - ${EpisodeNumber} [${MiscInfo}]${Extension}
Using Regex.Replace, the file TestFile 101.mkv, I get []TestFile - 1[].mkv. What I want to do is make it so that [] is only included if the group FanSub or MiscInfo was found.
I can solve this with a MatchEvaluator because I actually get to compile a function. But this would not be a easy solution for users of the program. The only other idea I have to solve this is to actually make my own Regex.Replace function that accepts special syntax.
It sounds like you want to be able to specify an arbitrary format dynamically rather than hard-code it into your code.
Perhaps one solution is to break your filename parts into specific groups then pass in a replacement pattern that takes advantage of those group names. This would give you the ability to pass in different replacement patterns which return the desired filename structure using the Regex.Replace method.
Since you didn't explain the categories of your filename I came up with some random groups to demonstrate. Here's a quick example:
string input = "Testing StupidName Number2 720p.mkv";
string pattern = #"^(?<Category>\w+)\s+(?<Name>.+?)\s+Number(?<Number>\d+)\s+(?<Resolution>\d+p)(?<Extension>\.mkv)$";
string[] replacePatterns =
{
"[${Category}]${Name} - ${Number}[${Resolution}]${Extension}",
"${Category} - ${Name} - ${Number} - ${Resolution}${Extension}",
"(${Number}) - [${Resolution}] ${Name} [${Category}]${Extension}"
};
foreach (string replacePattern in replacePatterns)
{
Console.WriteLine(Regex.Replace(input, pattern, replacePattern));
}
As shown in the sample, named groups in the pattern, specified as (?<Name>pattern), are referred to in the replacement pattern by ${Name}.
With this approach you would need to know the group names beforehand and pass these in to rearrange the pattern as needed.

Categories