1

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

Question :-

  1. How to check if string contain single slash and how to replace it?
  2. 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?

Harish
  • 789
  • 1
  • 7
  • 21
  • @TimBiegeleisen: Yes it does - note that it's a verbatim string literal. (If it weren't, it would give a compile-time error, as `\^` isn't a valid escape sequence.) – Jon Skeet Jul 13 '21 at 06:03
  • Does this answer your question? [Replace first occurrence of pattern in a string](https://stackoverflow.com/questions/8809354/replace-first-occurrence-of-pattern-in-a-string) – Eldar Jul 13 '21 at 06:03
  • @JonSkeet Sorry...I come from Java, hence my comment. You have 3 times as many points as I do, so you must be right `:-)` – Tim Biegeleisen Jul 13 '21 at 06:04
  • 1
    So when you say single slash you mean "slash with no slash before or after it"? – mjwills Jul 13 '21 at 06:05
  • 3
    what should be the result of `"///"`? unchanged or 4 slashes? – Cid Jul 13 '21 at 06:07
  • Pls check your expected result, i think it has some errors: *?i//y\^Pk@t9`n2 - why after 'y' one slash? – Mansur Kurtov Jul 13 '21 at 06:34
  • @MansurKurtov :- thanks! I have corrected it. – Harish Jul 13 '21 at 06:38
  • how can an invalid string come from user? I guess there is some UI involved? the inputs will be turned "automatically" to valid strings, don't they? What is your processing of the string making the input invalid? in your sample the string is hardcoded, so sure, the compiler mocks. But is this a runtime situation too? – dba Jul 13 '21 at 08:51
  • or even on reading a file.... I don't see, where this issue can rise with runtime-input at all – dba Jul 13 '21 at 09:00

3 Answers3

0
  1. 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

  1. 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
Joe
  • 1
  • 1
0

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(@"/",@"//");
Mansur Kurtov
  • 726
  • 1
  • 4
  • 12
0

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('/');
Philipp Ape
  • 519
  • 3
  • 13