-3

I want to exchange all occurences of a character in a string with their case-counterpart.

For example:

"%Y %m %d | %H:%M:%S"

should become

"%Y %M %d | %H:%m:%S"

for the character 'm' or 'M'.

How can I best do this in C# ?

xanatos
  • 109,618
  • 12
  • 197
  • 280
Marco
  • 301
  • 4
  • 15
  • Have you tried anything? – James Gould Mar 29 '17 at 10:35
  • The positions are fixed so pass the string to the ctor of a StringBuilder then you can change by index: sb[4] = 'M'; ... – Alex K. Mar 29 '17 at 10:37
  • Well, my idea is to convert it to a byte array and work on the single characters, converting lowercase 'm' to uppercase and uppercase 'M' to lowercase, but I thought there must be some simpler way to do this. Thanks for the idea with the StringBuilder, I will try that. – Marco Mar 29 '17 at 10:37
  • Enumerate the characters in the string and change them as needed. Then convert that `char[]` to a string – TheLethalCoder Mar 29 '17 at 10:38
  • 1
    Try following : string input = "%Y %m %d | %H:%M:%S"; string output = string.Join("",input.Select(x => (x == 'm') ? 'M' : (x == 'M') ? 'm' : x)); – jdweng Mar 29 '17 at 10:38

2 Answers2

1

You could use regexes... there are two possibilities here:

One using two distinct groupings and choosing which grouping was used in the replace function:

var rx1 = new Regex("(%M)|(%m)");

string original1 = "%Y %m %d | %H:%M:%S";
string modified1 = rx1.Replace(original1, x => x.Groups[1].Success ? "%m" : "%M");

The other simply taking a look in the replace function on what is the matched text.

var rx2 = new Regex("%[Mm]");

string original2 = "%Y %m %d | %H:%M:%S";
string modified2 = rx2.Replace(original2, x => x.Value == "%M" ? "%m" : "%M");

Just as a curiousity, I'll add two regexes that handle the escaping of a % with another %: %m is month, %%m is the string %m, %%%m is % plus the month.

var rx1 = new Regex("(?<=(?:^|[^%])(?:%%)*)(?:(%M)|(%m))");

and

var rx2 = new Regex("(?<=(?:^|[^%])(?:%%)*)%[Mm]");
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • While all answers work for the problem, I've marked this answer as correct answer because it contains a short and readable way of replacing the characters, same for the comment under the OP which uses String.Join and String.Select for replacing – Marco Mar 29 '17 at 11:05
0

For ASCII letters, the 6ᵗʰ bit can be used to switch between upper and lower case:

var s = "%Y %m %d | %H:%M:%S";
s = string.Concat(s.Select(c => (c | 32) == 'm' ? (char)(c ^ 32) : c));
Slai
  • 22,144
  • 5
  • 45
  • 53
  • 1
    @xanatos I have few more similar bit operation answers but can't remember what were the questions http://stackoverflow.com/questions/667802/what-is-the-algorithm-to-convert-an-excel-column-letter-into-its-number/41122035#41122035 – Slai Mar 30 '17 at 12:47