Why is this regex replace statement failing to do anything? [duplicate] - c#

This question already has answers here:
What is a word boundary in regex?
(13 answers)
Closed 3 years ago.
Below is a tiny method to basically replace the word "Stack" with ".png" in a string. So something called "Grid01Stack" would return as "Grid01.png" however the operation doesn't do anything at all, the string remains the same. What is going wrong? Here is the code:
private string GetUriFromName(string GridName)
{
string result = Regex.Replace(GridName, #"\bStack\b", ".png");
return (#"Resources/Images/"+result);
}

While you can simply do, per Yuri and Cid's suggestions:
GridName.Replace("Stack",".png")
This is not the best option if the word 'Stack' will ever appear more than once in the string, as it will replace all instances. So, for example, "Stack01Stack" will become ".png01.png". As you are trying to form a good filename, you really only want to replace the last occurence of "Stack" with ".png", and only if it at the end of the string. Therefore, using "Stack\b" as the comments suggested could end up messing with valid filenames as well, if Stack shows up multiple times. For instance, using that Regex "GridStack-01Stack" will become "Grid.png-01.png"
This is all based on speculation of what these strings might be, so this solution might not be necessary, but I'd recommend the following Regex, which will only change the word Stack if it occurs at the end of the string:
string result = Regex.Replace(GridName, "Stack$", ".png");

\bStack**\b** - is looking for the whole word 'Stack' with spaces, tab, line break, etc before and after word.
You just need the String.Replace for you case.

• String replace: string x = "Grid01Stack".Replace("Stack", ".png");
• Regex: string x = Regex.Replace("Grid01Stack", "[Ss]tack$", ".png");
The regex will search for Stack or stack which are always in the end of the string.

Related

How to split/extract complex string data c# [duplicate]

This question already has answers here:
Split a string by another string in C#
(11 answers)
Closed 5 years ago.
In this scenario the data I could have in my string may look like below but keep in mind the ids are dynamically generated so this isn't static and could be more than 2 if you haven't caught onto that.
ing:server blah blah, you. 2019,;:10-!gs.csd
1. id=value, otherid=value, pos=(22,22,33)
2. id=value2, otherid=value2, pos=(2g,2g,f) info other info info info info etc etc.
EDIT: How am I supposed to extract the individual values into strings afterwards from the string, the following does not work:
String valueString = "csd 1. id=value, otherid=value, pos=(22,22,33) ";
String value = valueString.Substring(valueString.IndexOf("otherid"), valueString.IndexOf(",") - valueString.IndexOf("otherid"));
You can do with Substring since you have already way of expecting when to start and when to end on your searching.
string result = x.Substring(x.IndexOf("csd"), (x.IndexOf("info ") - x.IndexOf("csd")));
I start searching on the start of the word "csd" and ends with the word "info " (with space), since there is also a word of info at the beginning of your string.
The result would be:
"csd 1. id=value, otherid=value, pos=(22,22,33) 2. id=value2, otherid=value2, pos=(24,21,33) "

Literal to string [duplicate]

This question already has answers here:
Can I expand a string that contains C# literal expressions at runtime
(5 answers)
Closed 6 years ago.
I have a literal as a string in a file
def s_CalculatePartiallyUsedTechPenalty(rate):\n total = min(rate,0)\n title = \"Partially Used Technology Penalty\" \n return RateItem(title,total,FinancialUniqueCode.PartiallyUsedTechPenalty,False)
when reading the file the text obviously looks like this:
def s_CalculatePartiallyUsedTechPenalty(rate):\\n total = min(rate,0)\\n title = \\\"Partially Used Technology Penalty\\\" \\n return RateItem(title,total,FinancialUniqueCode.PartiallyUsedTechPenalty,False)
Is there clean way to convert this string so that the value in the file is also the actual value of the string in code. In other words that that \n for example is \n and not \\n.
I understand that I can write a method that goes and replaces all the applicable values, but I do not want to do that unless it is the only way.
Edit: In response to John Wu's answer. No I am not confused. I do understand exactly that this is happening however I want to convert the literal value "\n" to the newline character. So instead of the literal value of \n it should be a new line.
Basically the inverse of How to convert a string containing escape characters to a string
You are confusing yourself. The string held in the file will be exactly the same as the string held in a string variable obtained by reading the file.
Perhaps you are using Visual Studio to inspect the string (i.e. using the Watch window or just hovering over the variable while the code is in debug mode). In this case, Visual Studio will display the extra slash to indicate that the string variable contains the literal value "\n" instead of a newline character.
If you want to eliminate the escape characters in the Watch window, you can append the format specifier ,nq to the variable name (link).
See also this question on StackOverflow.
If you can not fix file-writing code, that you can solve this issues in a following way:
String.Replace(#"\\\", #"\");
String.Replace(#"\\", #"\");
Or, in case, if you normal unescaped string,
String.Replace(#"\\\""", "\"");
String.Replace(#"\\n", Environment.NewLine);
P.s. Also think about other special characters, like \t
UPDATED:
Even better approach:
class Program
{
static void Main(string[] args)
{
var escaped = #"def s_CalculatePartiallyUsedTechPenalty(rate):\n total = min(rate,0)\n title = \""Partially Used Technology Penalty\"" \n return RateItem(title,total,FinancialUniqueCode.PartiallyUsedTechPenalty,False)";
var unescaped = Regex.Unescape(escaped);
Console.WriteLine(unescaped);
}
}

Is there a better way to check if an entire string was matched? [duplicate]

This question already has answers here:
Match exact string
(3 answers)
Closed 3 years ago.
I'm parsing a text file line by line and for each line I have a special regex. However in one case a pattern is matching two lines. One that is a correct match and another line only partialy because a couple of values are optional.
Invalid match:
BNE1010/1000 HKG1955/2005 7/PLD/CLD/YLD
matches patial string (shouln't match this at all):
BNE1010/1000
Correct match (matches the entire string):
RG878A/21AUG15 GIG/BOG 1/RG/AV 3/AV 4/AV 5/RG 6/AV081C/22 7/CDC/YD 9/TP
The regex for this is quite long and contains several optionl groups:
^(?<FlightDesignator>([A-Z0-9]{2}[A-Z]?)([0-9]{3,4}))(?<OperationalSuffix>[A-Z])?(?<FlightIdentifierDate>\/(\d{2})([A-Z]{3})?(\d{2})?)?(\s(?<FlightLegsChangeIdentifier>(\/?[A-Z]{3})+)(?=(\s|$)))?(\s1(?<JointOperationAirlineDesignators>(\/.{2}[A-Z]?)+))?(\s3\/(?<AircraftOwner>([A-Z]{2}|.)))?(\s4\/(?<CockpitCrewEmployer>(.+?)(?=(?: \d\/|$))))?(\s5\/(?<CabinCrewEmployer>([A-Z]{2}|.)))?(?<OnwardFlight>\s6\/(([A-Z0-9]{2}[A-Z]?)([0-9]{3,4}))([A-Z])?(\/(\d{2})([A-Z]{3})?(\d{2})?)?)?(\s7\/(?<MealServiceNote>(\/?[A-Z]{0,3})+))?(\s9\/(?<OperatingAirlineDisclosure>(.{2}[A-Z]?)))?
I think there is no need to study the entire regex becasue it's build dynamically from smaller patterns at runtime and all the parts work correctly. Also lots of combinations are tested with unit tests and they all work... as long as I try to parse ony the line that should be matched by the pattern.
Currently I'm checking if the entire string is matched by
match.Group[0].Value == line
but I find it's quite ugly. I know from JavaScript the regex engine provides an Index property where the regex engine stopped. So my idea was to compare the index with the length of the string. Unfortunatelly I wasn't able to find such a property in C#.
Another idea would be to modify the regex so that it matches only one line and no partial lines.
Example: https://regex101.com/r/dM5wU4/1
The example contains only two cases because there aren't actually any combinations that would change its behavior. I could remove some parameters but it wouldn't change anything.
EDIT:
I've edited my question. Sorry to every for not providing all the information at the first time. I won't ask any more questions when writing on the phone :) It wasn't a good idea. Hopefully it won't get closed now.
You asked whether I could simplify the regex. I would do it if I could and knew how. If it was easy I wouldn't have asked. The problem started as the regex ans string became bigger during development. Now they are at the production length and I can't actually make them shorter even for the sake of the quesion, sorry.
EDIT-2:
I found the reason why I couldn't find the inherited Index and Length properties of the Match class.
For some strange reason when selecting the Match class and pressing F1 Visual Studio opened the wrong help page (Match Properties) even though I'm not working with the Micro Framework. I didn't notice that but I was indeed wondering why there is very little information. Thx to #Jamiec for the correct link. I won't trust Visual Studio anymore when hitting F1.
Disclaimer: Im going to add this, but I doubt its the solution. If it's not this part will get deleted in short order
You can add a $ at the end of your regular expression. This stops your first example matching but continues to match the second example.
As you've not provided any more than 2 examples, its unclear if this actually solves all your cases or just that one specific false positive.
My question is whether it is possible to check if a regular expression matched the entire sting without checking the first group against the original line?
If you're not adverse to checking the entire match to the length of the string you can do that too:
var regex = new Regex(#"^(?<FlightDesignator>([A-Z0-9]{2}[A-Z]?)([0-9]{3,4}))(?<OperationalSuffix>[A-Z])?(?<FlightIdentifierDate>\/(\d{2})([A-Z]{3})?(\d{2})?)?(\s(?<FlightLegsChangeIdentifier>(\/?[A-Z]{3})+)(?=(\s|$)))?(\s1(?<JointOperationAirlineDesignators>(\/.{2}[A-Z]?)+))?(\s3\/(?<AircraftOwner>([A-Z]{2}|.)))?(\s4\/(?<CockpitCrewEmployer>(.+?)(?=(?: \d\/|$))))?(\s5\/(?<CabinCrewEmployer>([A-Z]{2}|.)))?(?<OnwardFlight>\s6\/(([A-Z0-9]{2}[A-Z]?)([0-9]{3,4}))([A-Z])?(\/(\d{2})([A-Z]{3})?(\d{2})?)?)?(\s7\/(?<MealServiceNote>(\/?[A-Z]{0,3})+))?(\s9\/(?<OperatingAirlineDisclosure>(.{2}[A-Z]?)))?");
var input1 = #"BNE1010/1000 HKG1955/2005 7/PLD/CLD/YLD";
var input2 = #"RG878A/21AUG15 GIG/BOG 1/RG/AV 3/AV 4/AV 5/RG 6/AV081C/22 7/CDC/YD 9/TP";
var match1 = regex.Match(input1);
var match2 = regex.Match(input2);
Console.WriteLine(match1.Length == input1.Length); // False
Console.WriteLine(match2.Length == input2.Length); // True
Live example: http://rextester.com/NIBE6349

Parsing a String for Special characters in C#

I am getting a string in the following format in the query string:
Arnstung%20Chew(20)
I want to convert it to just Arnstung Chew.
How do I do it?
Also how do I make sure that the user is not passing a script or anything harmful in the query string?
string str = "Arnstung Chew (20)";
string replacedString = str.Substring(0, str.IndexOf("(") -1 ).Trim();
string safeString = System.Web.HttpUtility.HtmlEncode(replacedString);
It's impossible to provide a comprehensive answer without knowing what variations might appear on your input text. For example, will there always be two words separated by a space followed by a number in parentheses? Or might there be other variations as well?
I have a lot of parsing code on my Black Belt Coder site, including a sscanf() replacement for .NET that may potentially be useful in your case.

Extracting a string starting with x and ending with y

First of all, I did a search on this and was able to find how to use something like String.Split() to extract the string based on a condition. I wasn't able to find however, how to extract it based on an ending condition as well. For example, I have a file with links to images: http://i594.photobucket.com/albums/tt27/34/444.jpghttp://i594.photobucket.com/albums/as/asfd/ghjk6.jpg
You will notice that all the images start with http:// and end with .jpg. However, .jpg is succeeded by http:// without a space, making this a little more difficult.
So basically I'm trying to find a way (Regex?) to extract a string from a string that starts with http:// and ends with .jpg
Regex is the easiest way to do this. If you're not familiar with regular expressions, you might check out Regex Buddy. It's a relatively cheap little tool that I found extremely useful when I was learning. For your particular case, a possible expression is:
(http://.+?\.jpg)
It probably requires some more refinement, as there are boundary cases that could trip this up, but it would work if the file is a simple list.
You can also do free quick testing of expressions here.
Per your latest comment, if you have links to other non-images as well, then you need to make sure it doesn't start at the http:// for one link and read all the way to the .jpg for the next image. Since URLs are not allowed to have whitespace, you can do it like this:
(http://[^\s]+\.jpg)
This basically says, "match a string starting with http:// and ending with .jpg where there is at least one character between the two and none of those characters are whitespace".
Regex RegexObj = new Regex("http://.+?\\.jpg");
Match MatchResults = RegexObj.Match(subject);
while (MatchResults.Success) {
//Do something with it
MatchResults = MatchResults.NextMatch();
}
In your specific case, you could always split if by ".jpg". You will probably end up with one empty element at the end of the array, and have to append the .jpg at the end of each file if you need that. Apart from that I think it would work.
Tested the following code and it worked fine:
public void SplitTest()
{
string test = "http://i594.photobucket.com/albums/tt27/34/444.jpghttp://i594.photobucket.com/albums/as/asfd/ghjk6.jpg";
string[] items = test.Split(new string[] { ".jpg" }, StringSplitOptions.RemoveEmptyEntries);
}
It even get rid of the empty entry...
The following LINQ will separate by http: and make sure to only get values that end with jpg.
var images = from i in imageList.Split(new[] {"http:"},
StringSplitOptions.RemoveEmptyEntries)
where i.EndsWith(".jpg")
select "http:" + i;

Categories