How to split string into methode name and its arguments? C# - c#

I'm looking for generic and reliable method to split string that is actualy a method name and its arguments in a way that I can determine which element is a methode name and which is an argument. Let's say I have several examples like those:
(GetCurrentValues(Self, LD.Id, LBH))
(value(The_Origin(hDistr)))
(GetSomeStatus(Some_Description(hDistr), BT.A_status))
I don't expect a working example but rather some ideas how to handle this kind of cases, working example would be great thoug.
I know I can use char[] delimiterChars = { '(', ')' }; but this seem to be very naive approach.

Related

String.Split doesn't appear to be using overloads correctly

Simple issue of whenever I ported over a console app class into a Windows Form class, the only thing that bricked was using String.Split to separate into a specified number of sub strings. Not sure why this is the case as I can peek the overloads and can confirm that the char[], int overload is there. Here's a picture.
As you're trying to use this version of the String.Split method, your first argument needs to be an array.
Here is a list of overloads that are supported.
Using String.Split(',') works since that overload specifies that the separator argument is a params argument.
However, when you want to use the Split(char[], int) overload, the first argument is not specified as a params argument, which means you have to use that method like this:
var sections = line.Split(new[] {','}, 3);
There's no overload that takes a single character. You want the one that takes an array:
string[] parts = line.Split(new char[]{','}, 3)

How to localize a string in unity where different languages may have different grammars

I'm translating a Unity game and some of the lines go like
Unlock at XXXX
where "XXXX" is replaced at runtime by an arbitrary substring. Easy enough to replace the wildcards, but to translate the quote, I can't simply concatenate a + b, as some languages will have the value before or inside the string. I figured I needed to, effectively, de-replace it, ie isolate and keep the substring and translate whatever's around it.
Problem is that while I can easily do the second part, I can't think of any avenues for the first. I know to get the character index of what I'm looking for, but the value takes up an arbitrary number of characters, and I can't use whitespace since some languages don't use it. Can't use digit detection since not all of the values are going to be numbers. I tried asking Google, but I couldn't translate "find whatever replaces a wildcard" into something keyword-searchable.
In short, what I'm looking for is a way to find the "XXXX" (the easy part) and then find whatever replaces it in the string (the less-easy part).
Thanks in advance.
I eventually found a workaround, thanks to everybody's kind advice. I stored the substring and referred to it in a special translation method that does take in a value. Thanks for your kind help, everybody.
public static string TranslateWithValue (string text, string value, int language) {
string sauce = text.Replace (value, "XXXX");
sauce = Translate (sauce, language);
sauce = sauce.Replace ("XXXX", value);
return sauce;
}
Usually, I use string.Format in such cases. In your case, I'd declare 2 localizeable strings:
string unlockFormat = "Unlock at {0}";
string unlockValue = "next level";
When you need the unlock condition displayed, you can combine the strings like that:
string unlockCondition = string.Format(unlockFormat, unlockValue);
which will produce the string "Unlock at next level".
Both unlockFormat and unlockValue can be translated, and the translator can move {0} wherever needed.

C# CS1502: Best Overloaded Match not finding the correct function in the docs

I am working with the C# Mono Compiler and the complier keeps giving me the CS1502 error due to not being able to find the correct function in the Docs. Specifically, I am getting problems with the Split function in the String API with the following message
The best overloaded method match for `string.Split(params char[])' has some invalid arguments
when I am trying to use the Split(String[], StringSplitOptions) function outlined on this page: https://msdn.microsoft.com/en-us/library/tabh47cf(v=vs.110).aspx
, which is found in the API documentation: https://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx
Edit: The piece of code I am trying to write is this:
words = line.Split("\t");
I am trying to split a tab-separated String (the variable 'line') into an array of strings 'words'.
Pass the tab (\t) as a char not a string using enclosing single quotes vs. double quotes, i.e.:
words = line.Split('\t');

Why is TextInfo.ListSeparator returned as a string?

Apologies if this has been asked before, but I couldn't find it if it has.
I am currently refactoring some code and removing the hard coded list seperator that I am splitting stuff with.
I am replacing it with TextInfo.ListSeparator from the System.Globalization namespace and noticed that it returns a string rather than a char.
Are there any cultures where more than a single character is used as a list seperator? Or is it completely safe to do something like this:
line.Split(culture.TextInfo.ListSeparator.First());
Assuming that it will only ever return a string that is one character in length.
Why not avoid the assumption and use something like
line.Split(new string[] {culture.TextInfo.ListSeparator}, StringSplitOptions.None);

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