How to invert parentheses? - c#

I want to convert this () into this ) (
Like for example (1+2) to ) 1+2(
i have tried this
char[] cArray = text.ToCharArray();
for (int i = 0; i < text.Length; i++)
{
if (cArray[i] == '(')
{
cArray[i] = ')';
}
if (cArray[i] == ')')
{
cArray[i] = '(';
}
}
string p=new string(cArray);
return p;
but it does not work

The problem is that after you've changed ( to ), the second if statement will immediately be true, so the character is flipped back again. The reverse isn't true though - if you start off with ) that will be flipped by the second statement, but then it won't be flipped back again. The net result is that all ) characters will be flipped to (, but that's all. So an input of "(((foo)))" would return "(((foo(((.
The simplest way to fix that is to use an else statement:
char[] cArray = text.ToCharArray();
for (int i = 0; i < text.Length; i++)
{
if (cArray[i] == '(')
{
cArray[i] = ')';
}
else if (cArray[i] == ')')
{
cArray[i] = '(';
}
}
return new string(cArray);
Alternatively, you could use a switch statement, which would be simpler if you had a lot of different cases to consider:
char[] cArray = text.ToCharArray();
for (int i = 0; i < text.Length; i++)
{
switch (cArray[i])
{
case '(':
cArray[i] = ')';
break;
case ')':
cArray[i] = '(';
break;
// No need for a default as it would be a no-op
}
}
return new string(cArray);
A switch statement will only evaluate the expression once (on each iteration, of course) so you don't need to worry about the two cases interfering with each other.

Use else before the second if as follows:
char[] cArray = text.ToCharArray();
for (int i = 0; i < text.Length; i++)
{
if (cArray[i] == '(')
{
cArray[i] = ')';
}
else if (cArray[i] == ')')
{
cArray[i] = '(';
}
}
string p = new string(cArray);
return p;

Related

Is it possible to escape Json string using System.Text.Json [duplicate]

Are there any classes/functions available to be used for easy JSON escaping? I'd rather not have to write my own.
I use System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
For those using the very popular Json.Net project from Newtonsoft the task is trivial:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(#"a\b");
Console.WriteLine(s);
....
This code prints:
"a\\b"
That is, the resulting string value contains the quotes as well as the escaped backslash.
Building on the answer by Dejan, what you can do is import System.Web.Helpers .NET Framework assembly, then use the following function:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
The Substring call is required, since Encode automatically surrounds strings with double quotes.
Yep, just add the following function to your Utils class or something:
public static string cleanForJSON(string s)
{
if (s == null || s.Length == 0) {
return "";
}
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
String t;
for (i = 0; i < len; i += 1) {
c = s[i];
switch (c) {
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ') {
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
} else {
sb.Append(c);
}
break;
}
}
return sb.ToString();
}
I have used following code to escape the string value for json.
You need to add your '"' to the output of the following code:
public static string EscapeStringValue(string value)
{
const char BACK_SLASH = '\\';
const char SLASH = '/';
const char DBL_QUOTE = '"';
var output = new StringBuilder(value.Length);
foreach (char c in value)
{
switch (c)
{
case SLASH:
output.AppendFormat("{0}{1}", BACK_SLASH, SLASH);
break;
case BACK_SLASH:
output.AppendFormat("{0}{0}", BACK_SLASH);
break;
case DBL_QUOTE:
output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE);
break;
default:
output.Append(c);
break;
}
}
return output.ToString();
}
In .Net Core 3+ and .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
The methods offered here are faulty.
Why venture that far when you could just use System.Web.HttpUtility.JavaScriptEncode ?
If you're on a lower framework, you can just copy paste it from mono
Courtesy of the mono-project #
https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
{
needEncode = true;
break;
}
}
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u{0:x4}", (int)c);
else switch ((int)c)
{
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
}
}
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
}
This can be compacted into
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{
private static bool NeedEscape(string src, int i)
{
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
}
public static string EscapeString(string src)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
{
sb.Append(src, start, i - start);
switch (src[i])
{
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
}
start = i + 1;
}
sb.Append(src, start, src.Length - start);
return sb.ToString();
}
}
I ran speed tests on some of these answers for a long string and a short string. Clive Paterson's code won by a good bit, presumably because the others are taking into account serialization options. Here are my results:
Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms
\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms
And here is the test code:
public static void Main(string[] args)
{
var testStr1 = "Apple Banana";
var testStr2 = #"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";
foreach (var testStr in new[] { testStr1, testStr2 })
{
var results = new Dictionary<string,List<long>>();
for (var n = 0; n < 10; n++)
{
var count = 1000 * 1000;
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
}
var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.Helpers.Json.Encode(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = cleanForJSON(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);
}
Console.WriteLine(testStr);
foreach (var result in results)
{
Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
}
Console.WriteLine();
}
Console.ReadLine();
}
I would also recommend using the JSON.NET library mentioned, but if you have to escape unicode characters (e.g. \uXXXX format) in the resulting JSON string, you may have to do it yourself. Take a look at Converting Unicode strings to escaped ascii string for an example.
I nice one-liner, used JsonConvert as others have but added substring to remove the added quotes and backslash.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
What about System.Web.Helpers.Json.Encode(...) (see http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111).aspx)?
String.Format("X", c);
That just outputs: X
Try this instead:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
There's a Json library at Codeplex
I chose to use System.Web.Script.Serialization.JavaScriptSerializer.
I have a small static helper class defined as follows:
internal static partial class Serialization
{
static JavaScriptSerializer serializer;
static Serialization()
{
serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
}
public static string ToJSON<T>(T obj)
{
return serializer.Serialize(obj);
}
public static T FromJSON<T>(string data)
{
if (Common.IsEmpty(data))
return default(T);
else
return serializer.Deserialize<T>(data);
}
}
To serialize anything I just call Serialization.ToJSON(itemToSerialize)
To deserialize I just call Serialization.FromJSON<T>(jsonValueOfTypeT)

How can I get the values new.TITLE['kinds.of'].food

I am new to regex. I have this string
new.TITLE['kinds.of'].food
or
new.TITLE['deep thought'].food
I want to retrieve these tokens:
new, TITLE, kinds.of, food.
or (2nd example)
new, TITLE, deep thought, food.
I can't simply split it with '.' I need regex match to get the values.
How is it done?
When working with tokens a parser (FST - Finite State Machine in this case) should do:
private static IEnumerable<string> ParseIt(string value) {
int lastIndex = 0;
bool inApostroph = false;
for (int i = 0; i < value.Length; ++i) {
char ch = value[i];
if (ch == '\'') {
inApostroph = !inApostroph;
continue;
}
if (inApostroph)
continue;
if (ch == '.' || ch == ']' || ch == '[') {
if (i - lastIndex > 0) {
if (value[lastIndex] != '\'')
yield return value.Substring(lastIndex, i - lastIndex);
else {
string result = value.Substring(lastIndex, i - lastIndex).Replace("''", "'");
yield return result.Substring(1, result.Length - 2);
}
}
lastIndex = i + 1;
}
}
if (lastIndex < value.Length)
yield return value.Substring(lastIndex);
}
Tests:
string test1 = #"new.TITLE['kinds.of'].food";
string test2 = #"new.TITLE['deep thought'].food";
string[] result1 = ParseIt(test1).ToArray();
string[] result2 = ParseIt(test2).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, result1));
Console.WriteLine(string.Join(Environment.NewLine, result2));
Outcome:
new
TITLE
kinds.of
food
new
TITLE
deep thought
food

StackOverflow exception in a recursive method

I've written a recursive method in C# that should indent strings. For example, this string:
for (int i = 0; i < sb.Length; i++)
{
if (sb[i] == '{')
{
startIndex = i;
break;
}
}
should be converted to:
for (int i = 0; i < sb.Length; i++)
{
if (sb[i] == '{')
{
startIndex = i;
break;
}
}
My method is (updated):
private static string IndentText(string t,bool first = true)
{
if (first == false)
{
t = t.PadLeft(2);
}
int startIndex = t.IndexOf('{') + 1;
int stopIndex = t.LastIndexOf('}') - 1;
int blockLength = stopIndex - startIndex + 1;
if (blockLength <= 1 )
{
return "";
}
string start = t.Substring(0, startIndex);
string end = t.Substring(stopIndex + 1);
string indentBlock = t.Substring(startIndex, blockLength);
if (!CheckNestedBlocks(indentBlock))
{
return indentBlock;
}
return start + IndentText(indentBlock,false) + end;
}
private static bool CheckNestedBlocks(string t)
{
for (int i = 0; i < t.Length; i++)
{
if (t[i] == '{') // { and } always come in pairs, so I can check of only one of then
{
return true;
}
}
return false;
}
But I'm getting a StackOverflow exception in mscorlib.dll
What is my mistake? Thanks in advance.
By the way, because I think I'm complicating this problem, is there a better (and working) way to indent strings like this?
You should not include the braces in the "block" that is passed in the recursive call:
if (t[i] == '{')
{
startIndex = i + 1; // Start one character beyond {
break;
}
// ...
if (t[i] == '}')
{
stopIndex = i - 1; // Stop one character prior to }
break;
}

how to use string.compare

There is an error with that string.compiler thingy and i dont know what to do. i really need some help please
char[] valWord = new char[100];
Console.WriteLine(textBox1.Text);
valWord = textBox1.Text;
int beg = 0;
int val = 0;
int value = 0;
for (int i = 0; i < 100; i++)
{
if (valWord[i] == ' ' || valWord[i] == '\0')
{
char[] temp = new char[100];
for (int j = 0; j < i - beg; j++)
{
temp[j] = valWord[beg + j];
}
temp[i - beg] = '\0';
//there is an error in this if statement: String.Compare
if (String.Compare(temp, "thousand") == 0)
{
value += (val*1000);
val = 0;
}
else if (String.Compare(temp, "hundred") == 0)
{
value += (val*100);
val = 0;
}
else if (String.Compare(temp, "one") == 0)
{
val = 1;
}
else if (String.Compare(temp, "two") == 0)
{
val = 2;
}
if (valWord[i] == '\0')
{
value += val;
break;
}
}
Console.WriteLine(textBox2.Text);
}
else
{
_list.Add(name, new GenericList());
}
You can't compare a string to a char array. They are different types.
Use if (string.Equals(new string(temp),"thousand")) instead.
As per MSDN, there is no such function overload defined for String.Compare

Trim a char array

Background: I was invited to an interview at a high profile company and I was asked the following question before being told I failed the interview for the position (C#,mvc3,razor). I'm genuinely interested in how to solve this.
Question: "Write a method that takes a char array, trims whitespace, and returns the same array." After some thinking I was told to replace the whitespace with "\o".
I started with:
public static char[] Trim(char[] c)
{
for (int i = 0; i < c.Length; i++)
{
if (c[i] == '\r' || c[i] == '\n' || c[i] == '\t')
{
c[i] = '\o';
}
}
}
I was told I have to use the same array, can't put it in a list and call ToArray(). However I think if the array stays the same size it is impossible to "trim it".
They may have meant \0 (NUL character), not dash-0
Assuming they meant to replace whitespace characters with null characters then the solution is simple:
Step 1: From the start of the string (represented as a character array) replace whitespace characters until a non-WS character is encountered.
Step 2: From the end of the string, working backwards, do the same.
public static void Trim( Char[] chars )
{
int maxIdx = 0; // an optimization so it doesn't iterate through chars already encountered
for( int i = 0;i < chars.Length; i++ )
{
if( Char.IsWhitespace( chars[i] ) )
{
chars[i] = '\0';
}
else
{
maxIdx = i;
break;
}
}
for( int i = chars.Length - 1; i > maxIdx; i-- )
{
if( Char.IsWhitespace( chars[i] ) ) chars[i] = '\0';
}
}
public static char[] Trim(char[] str)
{
return str.Where(x => !Char.IsWhiteSpace(x)).ToArray();
}
This is ugly and untested, but it does the whole thing in a single pass without creating a new array:
public static void Trim(Char[] str) {
int nonNullIndex = 0;
int lastNonNullIndex = 0;
for(int i=0;i<str.Length;i++) {
str[nonNullIndex] = str[i];
if( !Char.IsWhitespace( str[i] ) || nonNullIndex > 0) nonNullIndex++;
if( !Char.IsWhitespace( str[i] )) lastNonNullIndex = i;
}
nonNullIndex++
str[lastNonNullIndex] = '\0';
}
I guess what you might have been asked is to remove white space from between the string and then fill the char array for the remaining elements of the array with '\0'
e.g. "Convert this string" to "Convertthisstring" and fill the remaining array with 2 '\0'
Solution:
char[] TrimWhiteSpace(char[] source)
{
int i, j = 0;
for (i = 0; i < source.Length; i++)
{
if (!char.IsWhiteSpace(source[i]))
{
source[j] = source[i];
j++;
}
}
for (int x = 0; x < (i - j); x++)
{
source[j + x] = '\0';
}
return source;
}

Categories

Resources