My requirement
If string contains single slash (/ or \) it should be replace with
double slash
Note :- string is randomly generated so, I have no control.
e.g. I have string
string str = #"*?i//y\^Pk#t9`n2";
When I tried as
str = str.Replace(#"\", #"\\").Replace(#"/",#"//");
it replaced // with //// but I need to replace only single slash(\) with double slash(\\).
Above code actual result is
*?i////y\^Pk#t9`n2
expected result is
*?i//y\\^Pk#t9`n2
Note :- If string contain double slash in sequence like "//" or "\\" then no need to modify string. but string contains single slash (/ or \) need to replace with double slash.
I have tried to find out other approach then I found following stack-overflow already question-answer
Replace single backslash with double backslash
Replace "\\" with "\" in a string in C#
How to change backslash to double backslash?
Question :-
How to check if string contain single slash and how to replace it?
What best practice should follows while doing string manipulation like this?
Edit :-
I have random generated string comes from user like.
string str = #"*?i//y\^Pk#t9`n2";
sometimes that string contain single slash as above (\). if we consider above string without verbatim(#) it is not a valid string in C#. it gives compile time error. to make above string valid I need to replace "\" with "\\".
How I can achieve this?
Pls try this, first i repleced all double slash with single slash and then vice versa:
var str = #"*?i//y\^Pk#t9`n2";
var tempStr = str.Replace(#"\\", #"\").Replace(#"//",#"/");
var result = tempStr.Replace(#"\", #"\\").Replace(#"/",#"//");
I had to do two Regex.Replace and use look arounds to achieve this. The final solution was
Regex.Replace(Regex.Replace(str, #"(?<!\/)\/(?!\/)", #"//"), #"(?<!\\)\\(?!\\)", #"\\")
If you've never dealt with regex before, it can be a beast. Essentially I am looking for all backslashes and forward slashes (\\ and \/ escaped) and once I match a backslash and forward slash, I am going to use negative lookbehinds and negative aheads to not match if it there is a match in front or behind it.
Negative Look Behind:
(?<!\/)
Negative Look Ahead:
(?!\/)
I am then repeating it twice for forward slashes and backwards slashes
The best solution might be to roll your own algorithm. Step through the string character by character looking for a slash, and if it finds one, check the next character and previous, if 1 of those exist, then do not insert a duplicate slash because that means it is not alone
This replaces all of the individual occurrences of a character and also fills up an odd number of occurrences:
public static string ReplaceSingle(this string s, char needle)
{
var valueSpan = s.AsSpan();
var length = valueSpan.Length * 2;
char[]? resultArray = null;
Span<char> resultSpan = length <= 256
? stackalloc char[length]
: (resultArray = ArrayPool<char>.Shared.Rent(length));
var value = char.MinValue;
var written = 0;
for (int index = 0; index < valueSpan.Length; index++)
{
value = valueSpan[index];
resultSpan[written++] = value;
if (value == needle && ++index < valueSpan.Length)
{
value = valueSpan[index];
resultSpan[written++] = value == needle ? value : needle;
}
}
var result = new string(resultSpan[..written]);
resultSpan.Clear();
if (resultArray is not null) ArrayPool<char>.Shared.Return(resultArray);
return result;
}
For instance, if you have / it will turn to //, but // will remain. However /// will turn to //// and so on.
There is also a usage of ArrayPool and stackalloc which are aimed at better performance.
Usage:
string value = "This/ is a //Test ///!";
string result = value.ReplaceSingle('/');
Related
I want to replace a string if it is a part of another string from both ends.
Say for example a string +35343+3566. I want to replace +35 with 0 only if it is surrounded with characters from both sides. So desired outcome would be +35343066.
Normally I'd use line.Replace("+35", "0") and perhaps if-else to meet a condition
string a = "+35343+3566";
string b = a.Replace("+35", "0");
I would want 'b = +35343066 and not b = 0343066`
You can use regex for this. For example:
var replaced = Regex.Replace("+35343+3566", "(?<=.)(\\+35)(?=.)", "0");
// replaced will contain +35343066
So what this pattern is saying is that +35 (\\+35) must have one character behind (?<=.) and one character ahead (?=.)
You can do this with a Regular Expression, as follows:
string a = "+35343+3566";
var regex = new Regex(#"(.)\+35(.)"); // look for "+35" between any 2 characters, while remembering the characters that were found in ${1} and ${2}
string b = regex.Replace(a, "${1}0${2}"); // replace all occurences with "0" surrounded by both characters that were found
See Fiddle: https://dotnetfiddle.net/OdCKsy
Or slightly simpler, if it turns out that only the prefix character matters:
string a = "+35343+3566";
var regex = new Regex(#"(.)\+35"); // look for a character followed by "+35", while remembering the character that was found in ${1}
string b = regex.Replace(a, "${1}0"); // replace all occurences with the character that was found followed by a 0
See Fiddle: https://dotnetfiddle.net/9jEHMN
I have a string which I extract from an HTML document like this:
var elas = htmlDoc.DocumentNode.SelectSingleNode("//a[#class='a-size-small a-link-normal a-text-normal']");
if (elas != null)
{
//
_extractedString = elas.Attributes["href"].Value;
}
The HREF attribute contains this part of the string:
gp/offer-listing/B002755TC0/
And I'm trying to extract the B002755TC0 value, but the problem here is that the string will vary by its length and I cannot simply use Substring method that C# offers to extract that value...
Instead I was thinking if there's a clever way to do this, to perhaps a match beginning of the string with what I search?
For example I know for a fact that each href has this structure like I've shown, So I would simply match these keywords:
offer-listing/
So I would find this keyword and start extracting the part of the string B002755TC0 until the next " / " sign ?
Can someone help me out with this ?
This is a perfect job for a regular expression :
string text = "gp/offer-listing/B002755TC0/";
Regex pattern = new Regex(#"offer-listing/(\w+)/");
Match match = pattern.Match(text);
string whatYouAreLookingFor = match.Groups[1].Value;
Explanation : we just match the exact pattern you need.
'offer-listing/'
followed by any combination of (at least one) 'word characters' (letters, digits, hyphen, etc...),
followed by a slash.
The parenthesis () mean 'capture this group' (so we can extract it later with match.Groups[1]).
EDIT: if you want to extract also from this : /dp/B01KRHBT9Q/
Then you could use this pattern :
Regex pattern = new Regex(#"/(\w+)/$");
which will match both this string and the previous. The $ stands for the end of the string, so this literally means :
capture the characters in between the last two slashes of the string
Though there is already an accepted answer, I thought of sharing another solution, without using Regex. Just find the position of your pattern in the input + it's lenght, so the wanted text will be the next character. to find the end, search for the first "/" after the begining of the wanted text:
string input = "gp/offer-listing/B002755TC0/";
string pat = "offer-listing/";
int begining = input.IndexOf(pat)+pat.Length;
int end = input.IndexOf("/",begining);
string result = input.Substring(begining,end-begining);
If your desired output is always the last piece, you could also use split and get the last non-empty piece:
string result2 = input.Split(new string[]{"/"},StringSplitOptions.RemoveEmptyEntries)
.ToList().Last();
Slightly similar to this question, I want to replace argv contents:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
to this:
"-help=none\n-URL=(default)\n-password=********\n-uname=Khanna\n-p=100"
I have tried very basic string find and search operations (using IndexOf, SubString etc.). I am looking for more elegant solution so as to replace this part of string:
-password=AnyPassword
to:
-password=*******
And keep other part of string intact. I am looking if String.Replace or Regex replace may help.
What I've tried (not much of error-checks):
var pwd_index = argv.IndexOf("--password=");
string converted;
if (pwd_index >= 0)
{
var leftPart = argv.Substring(0, pwd_index);
var pwdStr = argv.Substring(pwd_index);
var rightPart = pwdStr.Substring(pwdStr.IndexOf("\n") + 1);
converted = leftPart + "--password=********\n" + rightPart;
}
else
converted = argv;
Console.WriteLine(converted);
Solution
Similar to Rubens Farias' solution but a little bit more elegant:
string argv = "-help=none\n-URL=(default)\n-password=\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)[^\n]*", "$1********");
It matches password= literally, stores it in capture group $1 and the keeps matching until a \n is reached.
This yields a constant number of *'s, though. But telling how much characters a password has, might already convey too much information to hackers, anyway.
Working example: https://dotnetfiddle.net/xOFCyG
Regular expression breakdown
( // Store the following match in capture group $1.
password= // Match "password=" literally.
)
[ // Match one from a set of characters.
^ // Negate a set of characters (i.e., match anything not
// contained in the following set).
\n // The character set: consists only of the new line character.
]
* // Match the previously matched character 0 to n times.
This code replaces the password value by several "*" characters:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)([\s\S]*?\n)",
match => match.Groups[1].Value + new String('*', match.Groups[2].Value.Length - 1) + "\n");
You can also remove the new String() part and replace it by a string constant
I need to get the first char of this string:
String s = "X-4711";
And put it after the number with an ';' , like: 4711;X.
I already tried it with:
String x = s.Split("-")[1] + ";" + s.Split("-")[0];
then I get it, but can I do it better or is this the only possible way?
var items = s.Split ("-");
string x = String.Format ("{0};{1}", items[1], items[0]);
At most this makes it a little more readable and a micro-optimisation of only having to split once.
EDIT :
As some of the comments have pointed out, if you are using C#6 you can make use of String Interpolation to format the string. It does the exact same thing, only looks a little better.
var items = s.Split ("-");
string x = $"{items[1]};{items[0])}";
Not sure what performance you are looking for small string operations, your code is well written and satisfy your needs.
One minor thing you might consider is removing additional split performed on input string.
var subs = s.Split ("-");
String.Format ("{0};{1}", subs [1], subs [0]);
If you are looking single liner (crazy programmer), this might help.
string.Join(";", s.Split('-').Reverse())
String.Substring: Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.
string sub = input.Substring(0, 1);
string restStr = input.Substring(2, input.length-2);
// string restStr = input.Substring(2); Can also use this instead of above line
string madeStr = restStr + ";" + sub;
You call the Substring method to extract a substring from a string that begins at a specified character position and ends before the end of the string. The starting character position is a zero-based; in other words, the first character in the string is at index 0, not index 1. To extract a substring that begins at a specified character position and continues to the end of the string, call the Substring method.
I'm trying to match on some inconsistently formatted HTML and need to strip out some double quotes.
Current:
<input type="hidden">
The Goal:
<input type=hidden>
This is wrong because I'm not escaping it properly:
s = s.Replace(""","");
This is wrong because there is not blank character character (to my knowledge):
s = s.Replace('"', '');
What is syntax / escape character combination for replacing double quotes with an empty string?
I think your first line would actually work but I think you need four quotation marks for a string containing a single one (in VB at least):
s = s.Replace("""", "")
for C# you'd have to escape the quotation mark using a backslash:
s = s.Replace("\"", "");
I didn't see my thoughts repeated already, so I will suggest that you look at string.Trim in the Microsoft documentation for C# you can add a character to be trimmed instead of simply trimming empty spaces:
string withQuotes = "\"hellow\"";
string withOutQotes = withQuotes.Trim('"');
should result in withOutQuotes being "hello" instead of ""hello""
s = s.Replace("\"", "");
You need to use the \ to escape the double quote character in a string.
You can use either of these:
s = s.Replace(#"""","");
s = s.Replace("\"","");
...but I do get curious as to why you would want to do that? I thought it was good practice to keep attribute values quoted?
s = s.Replace("\"",string.Empty);
c#: "\"", thus s.Replace("\"", "")
vb/vbs/vb.net: "" thus s.Replace("""", "")
If you only want to strip the quotes from the ends of the string (not the middle), and there is a chance that there can be spaces at either end of the string (i.e. parsing a CSV format file where there is a space after the commas), then you need to call the Trim function twice...for example:
string myStr = " \"sometext\""; //(notice the leading space)
myStr = myStr.Trim('"'); //(would leave the first quote: "sometext)
myStr = myStr.Trim().Trim('"'); //(would get what you want: sometext)
You have to escape the double quote with a backslash.
s = s.Replace("\"","");
s = s.Replace(#"""", "");
This worked for me
//Sentence has quotes
string nameSentence = "Take my name \"Wesley\" out of quotes";
//Get the index before the quotes`enter code here`
int begin = nameSentence.LastIndexOf("name") + "name".Length;
//Get the index after the quotes
int end = nameSentence.LastIndexOf("out");
//Get the part of the string with its quotes
string name = nameSentence.Substring(begin, end - begin);
//Remove its quotes
string newName = name.Replace("\"", "");
//Replace new name (without quotes) within original sentence
string updatedNameSentence = nameSentence.Replace(name, newName);
//Returns "Take my name Wesley out of quotes"
return updatedNameSentence;
s = s.Replace( """", "" )
Two quotes next to each other will function as the intended " character when inside a string.
if you would like to remove a single character i guess it's easier to simply read the arrays and skip that char and return the array. I use it when custom parsing vcard's json.
as it's bad json with "quoted" text identifiers.
Add the below method to a class containing your extension methods.
public static string Remove(this string text, char character)
{
var sb = new StringBuilder();
foreach (char c in text)
{
if (c != character)
sb.Append(c);
}
return sb.ToString();
}
you can then use this extension method:
var text= myString.Remove('"');