How to reverse a string that contains Hebrew letters and numbers? - c#

i have an hebrew string that i need to reverse.
"שורה שלמה בעברית 3/8" וגם נושא חדש בסוגריים (הנושא) וגם מספר בסוגריים (25) וגם נקודה בסוף משפט."
i used this function to reverse it
public static string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
the output is:
".טפשמ ףוסב הדוקנ םגו )52( םיירגוסב רפסמ םגו )אשונה( םיירגוסב שדח אשונ םגו \"8/3 תירבעב המלש הרוש"
as you can see the words in hebrew where reverse successfully but the numbers and () are reversed.

static public string ReverseOnlyHebrew(string str)
{
string[] arrSplit;
if (str != null && str != "")
{
arrSplit = Regex.Split(str, "( )|([א-ת]+)");
str = "";
int arrlenth = arrSplit.Length - 1;
for (int i = arrlenth; i >= 0; i--)
{
if (arrSplit[i] == " ")
{
str += " ";
}
else
{
if (arrSplit[i] != "")
{
int outInt;
if (int.TryParse(arrSplit[i], out outInt))
{
str += Convert.ToInt32(arrSplit[i]);
}
else
{
arrSplit[i] = arrSplit[i].Trim();
byte[] codes = System.Text.ASCIIEncoding.Default.GetBytes(arrSplit[i].ToCharArray(), 0, 1);
if (codes[0] > 47 && codes[0] < 58 || codes[0] > 64 && codes[0] < 91 || codes[0] > 96 && codes[0] < 123)//EDIT 3.1 reverse just hebrew words
{
str += arrSplit[i].Trim();
}
else
{
str += Reverse(arrSplit[i]);
}
}
}
}
}
}
return str;
}
static public string Reverse(string str)
{
char[] strArray = str.ToCharArray();
Array.Reverse(strArray);
return new string(strArray);
}

public static string Reverse(string t)
{
char[] charArray = t.ToCharArray();
string a = "";
int last = 0;
for (int i = 0; i <= charArray.Length-1; i++)
{
if (!IsHebrew(charArray[i]))
{
List<char> temp = new List<char>();
for (; last < i; last++)
{
int k = 0;
temp.Insert(0,charArray[last]);
}
foreach(char g in temp)
{
a += g.ToString();
}
a += charArray[i];
last += 1;
}
}
return a;
}
private const char FirstHebChar = (char)1488; //א
private const char LastHebChar = (char)1514; //ת
private static bool IsHebrew(char c)
{
return c >= FirstHebChar && c <= LastHebChar;
}

Related

Get Last Four word after splitting a string

I have two string like below
var str1 = '20180215.20150215.3.1.0.0';
var str2 = '20180215.3.1.0.0';
I need to get the last four word after splitting these string with .
var str1Arr = str1.split('.')
What i need is a generic method to get last four words 3.1.0.0.
Thanks
var lastFour = str1Arr.Reverse().Take(4).Reverse().ToArray();
public static class SplitExtension
{
public static string LastNItems(this string str, int nItem, char separator = '.')
{
return string.Join(separator.ToString(), str.Split(separator).Reverse().Take(nItem).Reverse());
}
public static string[] LastNItems(this string[] strArray, int nItem)
{
return strArray.Reverse().Take(nItem).Reverse().ToArray();
}
}
This will enable you to do
var str1 = "20180215.20150215.3.1.0.0";
var str1Last4 = str1.LastNItems(4); // "3.1.0.0"
var str1Last4Items = str1.Split('.').LastNItems(4); // ["3","1","0","0"]
or for completion
var str1Last4Items = str1.LastNItems(4).Split('.'); // ["3","1","0","0"]
You can use it by extension methods.
public static class CommonExtension
{
public static List<string> LastNItem(this string str, int nItem, string separator = ".")
{
var splittedWords = str.Split(new [] { separator }, StringSplitOptions.None);
var res = splittedWords.Reverse().Take(nItem).Reverse().ToList();
return res;
}
}
Then you can call it everywhere you want.
var str1 = "1.0.0";
var str2 = "20180215.3.1.0.0";
var str1Last4 = str1.LastNItem(4);
var str2Last4 = str2.LastNItem(4);
Why not just Skip top Length - 4 items?
string str1 = "20180215.20150215.3.1.0.0";
string[] str1Arr = str1.Split('.');
var result = str1Arr
.Skip(str1Arr.Length - 4)
.ToArray(); // if you want an array materialization
This code will do even when str1Arr.Length < 4 (in this case the entire str1Arr copy will be returned). In case you want a string as the result you can just try Substring (without creating any arrays)
string str1 = "20180215.20150215.3.1.0.0";
string result = str1;
int index = result.Length;
for (int i = 0; i < 4; ++i) {
index = str1.LastIndexOf('.', index - 1);
if (index < 0)
break;
}
result = index < 0 ? result : result.Substring(index + 1);
public static string GetLastFour(string str)
{
string[] arr = str.Split('.');
System.Text.StringBuilder lastFour = new System.Text.StringBuilder();
if (arr.Length >= 4)
{
for (int k = arr.Length - 4; k < arr.Length; k++)
{
if (k == arr.Length - 1)
{
lastFour.Append(arr[k]);
}
else
{
lastFour.Append(arr[k] + ".");
}
}
}
return lastFour.ToString();
}
This would be faster than double reverse answer.
var str1 = "20180215.20150215.3.1.0.0";
var str2 = "20180215.3.1.0.0";
var words = str1.Split('.');
var toSkip = words.Length - 4;
var result = string.Join(".", words.Skip(toSkip));
A bit of testing showed that is is just slightly faster than double reverse.
What is 10 times faster than this one?
Well avoiding memory allocations and enumerations will be.
Here are the results of comparing 3 different extension methods for 10M iterations:
double reverse: 6463ms
split + skip: 5269ms
straight: 492ms
void Main()
{
var str1 = "20180215.20150215.3.1.0.0";
var numIterations = 10000000;
var timer = new Stopwatch();
timer.Start();
for (var i = 0; i < numIterations; i++)
{
str1.LastNItemsDoubleReverse(4);
}
timer.Stop();
timer.ElapsedMilliseconds.Dump("double reverse");
timer.Reset();
timer.Start();
for (var i = 0; i < numIterations; i++)
{
str1.LastNItemsSplitNSkip(4);
}
timer.Stop();
timer.ElapsedMilliseconds.Dump("split + skip");
timer.Reset();
timer.Start();
for (var i = 0; i < numIterations; i++)
{
str1.LastNItemsStraight(4);
}
timer.Stop();
timer.ElapsedMilliseconds.Dump("straight");
}
public static class ext
{
public static string LastNItemsDoubleReverse(this string str, int nItem, char separator = '.')
{
return string.Join(separator.ToString(), str.Split(separator).Reverse().Take(nItem).Reverse());
}
public static string LastNItemsSplitNSkip(this string str, int nItem, char separator = '.')
{
var words = str.Split(separator);
var toSkip = words.Length - nItem;
return string.Join($"{separator}", words.Skip(toSkip));
}
public static string LastNItemsStraight(this string str, int nItem, char separator = '.')
{
int j=1,i=str.Length-1;
for (;i>=0 && j<nItem;i--){
if(str[i]==separator) j++;
}
return str.Substring(i);
}
}
Try the following :
List<string> GetLastFourWords()
{
List<string> lastFour = new List<string>();
try
{
string[] arr = str1.split('.');
for(int i = 3; i >= 0; i-- )
{
lastFour.Add(arr[str1.length - 1 - i]);
}
}
catch(Exception ex)
{
}
return lastFour;
}

C# RNGCryptoServiceProvider and special characters

I'm looking for a way to get random characters.I need a string must be contain at 2 least uppercase letters, at least 1 number and special characters.
Here is my code:
public static string CreateRandomPassword(int Length)
{
string _Chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ[_!23456790";
Byte[] randomBytes = new Byte[Length];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
var chars = new char[Length];
int Count = _Chars.Length;
for(int i = 0;i<Length;i++)
{
chars[i] = _Chars[(int)randomBytes[i] % Count];
}
return new string(chars);
}
some results:
ZNQzvUPFKOL3x
BQSEkKHXACGO
They haven't special characters and numbers.
your code works great! I've just wrapped it with a function that validate your conditions.
I've executed the following:
public static string CreateRandomPassword(int Length)
{
string _Chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ[_!23456790";
Byte[] randomBytes = new Byte[Length];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
var chars = new char[Length];
int Count = _Chars.Length;
for (int i = 0; i < Length; i++)
{
chars[i] = _Chars[(int)randomBytes[i] % Count];
}
return new string(chars);
}
public static string CreateRandomPasswordWith2UpperAnd1NumberAnd1Special(int length)
{
while (true)
{
var pass = CreateRandomPassword(length);
int upper=0, num =0, special = 0,lower=0;
foreach (var c in pass)
{
if (c > 'A' && c < 'Z')
{
upper++;
}
else if (c > 'a' && c < 'z')
{
lower++;
}
else if (c > '0' && c < '9')
{
num++;
}
else
{
special++;
}
}
if (upper>=2&&num>=1&&1>=special)
{
return pass;
}
}
}
[Test]
public void CreateRandomPassword_Length13_RandomPasswordWithNumbers()
{
var random = CreateRandomPasswordWith2UpperAnd1NumberAnd1Special(13);
Assert.IsTrue(true);
}

How to add chars numerically in c#

So I'm building a program that takes a string and turns it into a binary number (I.E. "A" = 01000001). Then, if the user wishes, it can that binary number convert it back into a ascii character. Here the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
namespace NDR_011
{
class Program
{
public static Byte[] BinStr(String binary)
{
var list = new List<Byte>();
for (int i = 0; i < binary.Length; i += 8)
{
String t = binary.Substring(i, 8);
list.Add(Convert.ToByte(t, 2));
}
return list.ToArray();
}
public static void Print(object mess)
{
string tmp = mess.ToString().ToUpper();
Console.Write(tmp);
}
private static List<string> buffer = new List<string>();
private static string outfile = "C:/tmp/bytes.bin";
static void Main(string[] args)
{
string tmp = "";
Print("NDR 011\n");
while (true)
{
Print(""); tmp = Console.ReadKey().Key.ToString().ToUpper();
if (Console.CursorLeft > 0)
{
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
if (tmp == ConsoleKey.F1.ToString())
{
break;
} else if (tmp == ConsoleKey.F2.ToString())
{
comp();
continue;
} else if (tmp == ConsoleKey.F4.ToString())
{
buffer.Clear();
continue;
} else if (tmp == ConsoleKey.F5.ToString())
{
Print("N "); string a = Console.ReadLine();
outfile = a;
continue;
} else if (tmp == ConsoleKey.F5.ToString())
{
outfile = "C:/tmp/bytes.bin";
Print("Out file reset\n");
continue;
} else if (tmp == ConsoleKey.F7.ToString())
{
//Print("N "); // string a = Console.ReadLine();
string a = "C:/tmp/bytes.bin";
string[] s = File.ReadAllText(a).Split(' ');
char[] end = new char[s.Length - 1];
for (int i=0;i<end.Length;i++)
{
end[i] = (char)BinStr(s[i])[0];
//Print(end[i]);
}
//Print((char)BinStr(s[0])[0]);
if (end[0] == 'A' && end[1] == 'D' && end[2] == 'D')
{
for (int i=0+3;i<end.Length;i++)
{
int n = end[i] + end[i];
Print(n);
}
}
//decompile(a);
continue;
}
while (tmp.Length > 1)
{
char a = tmp[tmp.Length - 1];
tmp = a.ToString();
}
buffer.Add(tmp);
}
}
static void comp()
{
if (buffer == null || buffer.Count <= 0)
{
Print("Error buffer empty");
return;
}
char[] r = new char[buffer.Count];
for (int i=0;i<buffer.Count;i++)
{
r[i] = Convert.ToChar(buffer[i]);
Print(r[i]);
}
foreach (char ch in r)
{
string a = Convert.ToString((int)ch, 2);
while (a.Length != 8)
{
string b = "0";
a = b + a;
}
File.AppendAllText(outfile, a + " ");
}
Print("Compile done!\n");
}
static void decompile(string filename)
{
}
static void run()
{
}
}
}
(the indenation got messed up when I add to this post.)
The problem is this: when I try to add the values I get from the file I get random numbers like: 100102, and odd stuff like that. What am I doing wrong? Thanks
Here's how you convert a string to a binary string of 1s and 0s:
var binstring = string.Join(" ", Encoding.ASCII.GetBytes(("Welcome, World!")).Select(byt => Convert.ToString(byt, 2).PadLeft(8, '0')));
To convert that back into a string, we will need to a parse byte[] array from it with a method like so:
public static byte[] GetBytes(string s)
{
byte[] result = new byte[(s.Length + 7) / 8];
int i = 0;
int j = 0;
foreach (char c in s)
{
result[i] <<= 1;
if (c == '1')
result[i] |= 1;
j++;
if (j == 8)
{
i++;
j = 0;
}
}
return result;
}
Then we get those bytes and we can simply convert it into a string using:
Encoding.ASCII.GetString(GetBytes(binstring));
References: How could I encode a string of 1s and 0s for transport?How to get the binary code behind ASCII (C#)

C# Regular Expression to insert "_" after third, then seventh character with a new line after the eighth character

I was wondering if someone could help. I am trying to change a string in the below format:
goeirjew98rut34ktljre9t30t4j3der
to be outputted as below:
geo_irje_w
98r_ut34_k
tlj_re9t_3
0t4_j3de_r
So insert an underscore after the third and seventh characters and insert a new line after the eighth.
After doing some reading I thought the best way to do this might be via a regular expression such as the example at the below link:
http://msdn.microsoft.com/en-us/library/xwewhkd1(v=vs.110).aspx
However I am not sure how to modify this for my needs. Any help what so ever would be greatly appreciated.
Thanks
It can be easily solved by a regular expression and a Replace, like this:
var s = "goeirjew98rut34ktljre9t30t4j3der";
Regex.Replace(s, #"(\w{3})(\w{4})(\w{1})", "$1_$2_$3\n").Dump();
This is definitely something that is best solved with a quick loop:
string s = "goeirjew98rut34ktljre9t30t4j3der";
var outputs = new List<string>();
for (var i = 0; i < s.Length; i += 8)
{
string sub = s.Substring(i, Math.Min(8, s.Length - i));
if(sub.Length > 3)
sub = sub.Insert(3, "_");
if (sub.Length > 8)
sub = sub.Insert(8, "_");
outputs.Add(sub);
}
I think you can not insert char in string by this rule, but I hope this code be useful for you.
public string Decode(string str)
{
var state = 0;
var c = 0;
var newStr = string.Empty;
foreach (var ch in str)
{
c++;
newStr += ch;
if (state == 0 && c == 3)
{
newStr += "_";
state = 1;
c = 0;
}
if (state == 1 && c == 4)
{
newStr += "_";
state = 2;
c = 0;
}
if (state == 2 && c == 1)
{
newStr += "\r\n";
state = 0;
c = 0;
}
}
return newStr;
}
I would make it so u can change everything on the fly and use stringextentions
class Program
{
static void Main(string[] args)
{
string str = "goeirjew98rut34ktljre9t30t4j3der";
var parts = str.SplitInParts(8); //Split in different parts
foreach (var part in parts)
{
string formattedString = part.MultiInsert("_", 2, 6); //Insert your char on all position u want
Console.WriteLine(formattedString);
}
Console.ReadKey();
}
}
static class StringExtensions
{
public static IEnumerable<String> SplitInParts(this String s, Int32 partLength)
{
if (s == null)
throw new ArgumentNullException("s");
if (partLength <= 0)
throw new ArgumentException("Part length has to be positive.", "partLength");
for (var i = 0; i < s.Length; i += partLength)
yield return s.Substring(i, Math.Min(partLength, s.Length - i));
}
public static string MultiInsert(this string str, string insertChar, params int[] positions)
{
StringBuilder sb = new StringBuilder(str.Length + (positions.Length * insertChar.Length));
var posLookup = new HashSet<int>(positions);
for (int i = 0; i < str.Length; i++)
{
sb.Append(str[i]);
if (posLookup.Contains(i))
sb.Append(insertChar);
}
return sb.ToString();
}
}

Failing to convert TextBox_TextChanged() in C++ To C#

I was working on C++ with Juce Library for few months. I had written a code in my project where the formatting of textbox was modified to only hexadecimal values with few features:
Demonstratation:
12 ab 32 a5 64
Now if my cursor is at the end and i go on pressing backspace, it shud remove the values as it happens in a general text box.
Now If my cursor is at the beginning of a5, and i press "delete key", the value should become like:
12 ab 32 56 4
If my cursor is at the end of a5 and i press the 'delete key" nothing should happen. while entering the values space bar should not let spacing bw two values. Only a-f and 0-9 should be allowed to enter.
Code in C++ here:
void CMSP430CommPanel::textEditorTextChanged (TextEditor& editor)
{
if(&editor == m_texti2cWrite)
{
int count = 0;
int location;
String text1 = m_texti2cWrite->getText();
String text = m_texti2cWrite->getText().removeCharacters(" ");
String hexString = String::empty;
int countCaret = m_texti2cWrite->getCaretPosition();
for(int i=0; i < text.length(); i++)
{
hexString = hexString + String (&text[i], 1);
if((i+1) % 2 == 0)
{
if(i != text.length()-1)
{
hexString = hexString + T(" ");
count ++;
}
}
count ++;
}
m_texti2cWrite->setText(hexString,false);
if(text1.length() == m_texti2cWrite->getCaretPosition())
{
m_texti2cWrite->setCaretPosition(count);
}
else
{
m_texti2cWrite->setCaretPosition(countCaret);
}
}
}
I want the same thing to work in my WPF application. Lets say the general implementation of the same code in C#.
please help!!!
Try this (TextChanged-Event of your TextBox):
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox m_texti2cWrite = (TextBox)sender;
int count = 0;
string text1 = m_texti2cWrite.Text;
string text = m_texti2cWrite.Text.Replace(" ", string.Empty);
string hexString = string.Empty;
int countCaret = e.Changes.ToList()[0].Offset;
for (int i = 0; i < text.Length; i++)
{
hexString += text[i];
if ((i + 1) % 2 == 0)
{
if (i != text.Length - 1)
{
hexString = hexString + " ";
count++;
}
}
count++;
}
m_texti2cWrite.Text = hexString;
if (text1.Length == countCaret)
{
m_texti2cWrite.Select(count, 0);
}
else
{
if (e.Changes.ToList()[0].RemovedLength == 0)
{
m_texti2cWrite.Select(countCaret + 1, 0);
if (string.IsNullOrWhiteSpace(hexString.Substring(countCaret, 1)))
m_texti2cWrite.Select(countCaret + 2, 0);
}
else
{
m_texti2cWrite.Select(countCaret, 0);
if (string.IsNullOrWhiteSpace(hexString.Substring(countCaret, 1)))
m_texti2cWrite.Select(countCaret + 1, 0);
}
}
}
}
EDIT (only accept Digits, ControlKeys or a-f):
Add this method:
private Boolean IsTextAllowed(String text)
{
string acceptedChars = "ABCDEFabcdef";
foreach (Char c in text.ToCharArray())
{
if (Char.IsDigit(c) || Char.IsControl(c) || acceptedChars.Contains(c)) continue;
else return false;
}
return true;
}
Add the TextBox_PreviewTextInput-Event to your TextBox
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !IsTextAllowed(e.Text);
}
public class CMSP430CommPanel
{
//C++ TO C# CONVERTER WARNING: The original C++ declaration of the following method implementation was not found:
public void textEditorTextChanged(TextEditor editor)
{
if (editor == m_texti2cWrite)
{
int count = 0;
int location;
string text1 = m_texti2cWrite.getText();
string text = m_texti2cWrite.getText().removeCharacters(" ");
string hexString = string.empty;
int countCaret = m_texti2cWrite.getCaretPosition();
for (int i = 0; i < text.Length; i++)
{
hexString = hexString + (string)(text[i], 1);
if ((i + 1) % 2 == 0)
{
if (i != text.Length - 1)
{
hexString = hexString + T(" ");
count++;
}
}
count++;
}
m_texti2cWrite.setText(hexString,false);
if (text1.Length == m_texti2cWrite.getCaretPosition())
{
m_texti2cWrite.setCaretPosition(count);
}
else
{
m_texti2cWrite.setCaretPosition(countCaret);
}
}
}
}

Categories

Resources