Get language wise numbers using culture info in c# - c#

I'm working on language wise numbers and I'm doing it via CultureInfo.
CultureInfo class provide Native digit for Arabic and Gujarati language but not for Hindi.
For example:
My number is in English: 123456
Same number in Gujarati language: ૧૨૩૪૫6 (This is working fine)
For English language: १२३४५६ This is not working
What is the alternate option to display Hindi Native digit?
Example :
I want to display numbers in Hindi language: ०,१,२,३,४,५,६,७,८,९.
Here Is my code snippet:
CultureInfo languageculture = new CultureInfo("hi-IN");
NumberFormatInfo languageNumberFormat = languageculture.NumberFormat;
string[] nativeDigits = languageNumberFormat.NativeDigits;
string str5 = ConvertToMyLanguageDigits(i.ToString(), mydiditesgu);
Conversion (replace number) method:
private static string ConvertToMyLanguageDigits(string number, string[] myNative)
{
string myNewMuber = string.Empty;
myNewMuber = number;
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
string number1 = rgx.Replace(number, "");
var aa = number1.ToCharArray().Distinct().ToArray();
foreach (var item in aa)
{
if (!myNative.Any(x => x.Contains(item)))
{
myNewMuber = myNewMuber.Replace(item.ToString(), myNative[int.Parse(item.ToString())].ToString());
}
}
return myNewMuber;
}

Assuming you have the language pack installed on Windows, can't you do.
var hindiCulture = new CultureInfo("hi-IN");
To get the right culture. Then
var hindiDigits = hindiCulture.NumberFormat.NativeDigits;
to get the right digits?
For example, as demonstrated here
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
var hindiCulture = new CultureInfo("hi-IN");
Console.WriteLine(hindiCulture.EnglishName);
Console.WriteLine(hindiCulture.NativeName);
Console.WriteLine(string.Join("", hindiCulture.NumberFormat.NativeDigits));
}
}
outputs
Hindi (India)
हिंदी (भारत)
०१२३४५६७८९
As demonstrated here, If I do
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var hindiCulture = new CultureInfo("hi-IN");
Console.WriteLine(hindiCulture.EnglishName);
Console.WriteLine(hindiCulture.NativeName);
Console.WriteLine(string.Join("", hindiCulture.NumberFormat.NativeDigits));
Console.WriteLine(
ConvertToMyLanguageDigits("0123456789",
hindiCulture.NumberFormat.NativeDigits));
}
private static string ConvertToMyLanguageDigits(string number, string[] myNative)
{
string myNewMuber = string.Empty;
myNewMuber = number;
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
string number1 = rgx.Replace(number, "");
var aa = number1.ToCharArray().Distinct().ToArray();
foreach (var item in aa)
{
if (!myNative.Any(x => x.Contains(item)))
{
myNewMuber = myNewMuber.Replace(
item.ToString(),
myNative[int.Parse(item.ToString())].ToString());
}
}
return myNewMuber;
}
}
The output is
Hindi (India)
हिंदी (भारत)
०१२३४५६७८९
०१२३४५६७८९
There is no problem with your code or with .Net, I suspect you don't have you system set up properly, do you have the language pack installed?

Related

Multiple regex matches in single expression

I have the following sensitive data:
"Password":"123","RootPassword":"123qwe","PassPhrase":"phrase"
I would like to get the following safe data:
"Password":"***","RootPassword":"***","PassPhrase":"***"
It's my code:
internal class Program
{
private static void Main(string[] args)
{
var data = "\"Password\":\"123\",\"RootPassword\":\"123qwe\",\"PassPhrase\":\"phrase\"";
var safe1 = PasswordReplacer.Replace1(data);
var safe2 = PasswordReplacer.Replace2(data);
}
}
public static class PasswordReplacer
{
private const string RegExpReplacement = "$1***$2";
private const string Template = "(\"{0}\":\").*?(\")";
private static readonly string[] PasswordLiterals =
{
"password",
"RootPassword",
"PassPhrase"
};
public static string Replace1(string sensitiveInfo)
{
foreach (var literal in PasswordLiterals)
{
var pattern = string.Format(Template, literal);
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
sensitiveInfo = regex.Replace(sensitiveInfo, RegExpReplacement);
}
return sensitiveInfo;
}
public static string Replace2(string sensitiveInfo)
{
var multiplePattern = "(\"password\":\")|(\"RootPassword\":\")|(\"PassPhrase\":\").*?(\")"; //?
var regex = new Regex(string.Format(Template, multiplePattern), RegexOptions.IgnoreCase);
return regex.Replace(sensitiveInfo, RegExpReplacement);
}
}
Replace1 method works as expected. But it does it one by one. My question is is it possble to do the same but using single regex match ? If so I need help with Replace2.
The Replace2 can look like
public static string Replace2(string sensitiveInfo)
{
var multiplePattern = $"(\"(?:{string.Join("|", PasswordLiterals)})\":\")[^\"]*(\")";
return Regex.Replace(sensitiveInfo, multiplePattern, RegExpReplacement, RegexOptions.IgnoreCase);
}
See the C# demo.
The multiplePattern will hold a pattern like ("(?:password|RootPassword|PassPhrase)":")[^"]*("), see the regex demo. Quick details:
("(?:password|RootPassword|PassPhrase)":") - Group 1 ($1): a " char followed with either password, RootPassword or PassPhrase and then a ":" substring
[^"]* - any zero or more chars other than " as many as possible
(") - Group 2 ($2): a " char.

How to improve compile time using CSharpCodeProvider

I have an application where user can create its own formula it works fine
for all case but when i have DateTime Fields in my formula the compilation part of the code take around 132 ms for one formula where at the same time i
have 31 formula each with different value.
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
namespace abc
{
public class Abc
{
static void Main()
{
var code = #"
using System;
namespace First
{
public class program
{
public static int Main()
{
if(Convert.ToDateTime(""01-04-2019 10:25:00"")>Convert.ToDateTime(""01-04-2019 15:00:00""))
{
return 1;
}
else
{
return 0;
}
}
}
}";
Console.WriteLine(code);
var options = new CompilerParameters();
options.GenerateExecutable = false;
options.GenerateInMemory = false;
var provider = new CSharpCodeProvider();
var compile = provider.CompileAssemblyFromSource(options, code);
var type = compile.CompiledAssembly.GetType("First.program");
var abc = Activator.CreateInstance(type);
var method = type.GetMethod("Main");
var result = method.Invoke(abc, null);
Console.WriteLine(result); //output: abc
}
}
}
At this point
var compile = provider.CompileAssemblyFromSource(options, code);
It takes 132 ms but if don't use any date fields it takes 1 ms

C# - Extracting satellite two line elements from a text file

I'm very new to c# and programming in general so I apologise if this doesn't make sense...
I need to be able to search a textbox or combobox to read a notepad file containing many satellite two line element codes.
The text file is set out like this:
0 VANGUARD 1
1 00005U 58002B 14242.42781498 .00000028 00000-0 24556-4 0 2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A 14245.43855606 .00000265 00000-0 95096-4 0 2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A 14245.36883128 .00001088 00000-0 12832-3 0 1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434
Etc.
I need to search the box for the only satellite's name (the name after the 0 in the 'first' row) and extract that name into another textbox, and to use in my code. Additionally, I need to seperately extract the 2 lines of code directly beneath the name selected in the box (also to use in the code).
I have written code to use these two line elements, but I'm not able to automatically put them in my code.
Thank you
here is something that you can try quick and dirty that I have come up with.
1st place the file in a folder on your local hard drive.
2nd where I have filepath defined replace it with your actual file path and know how to use the # symbol and what it means in C#
3rd notice how I used the string .Replace Method.. you will have to tweak it I just gave you an Idea I am not going to write the entire code for you.. good luck.
static void Main(string[] args)
{
var fileName = string.Empty;
var filePath = #"C:\Users\myfolder\Documents\RGReports\"; //for testing purposes only
List<string> listNames = new List<string>();
string[] filePaths = Directory.GetFiles(#filePath);
foreach (string file in filePaths)
{
if (file.Contains(".txt"))
{
fileName = file;
using (StreamReader sr = File.OpenText(fileName))
{
//string s = String.Empty;
var tempFile = sr.ReadToEnd();
var splitFile = tempFile.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
foreach (string str in splitFile)
{
if (str.Length == 12)
{
listNames.Add(str.Substring(0, str.Length).Replace("0", "").Replace("1", "").Replace("2A",""));
}
Console.WriteLine(str);
}
}
}
}
}
Results will yield the following for names for example tested in a Console App
VANGUARD
TRANSIT
EXPLORER
You can use regular expressions for this task.
(I assume that the letters/numbers block after the name is also part of the name)
This code will do the following:
capture the name of the satellite and the two lines into a Satellite object
populate a ComboBox with the names of the satellite
whenever you selected a satellite you can know which one it was
a search box that searches for the first satellite beginning with the typed text
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private readonly BindingList<Satellite> _satellites = new BindingList<Satellite>();
private string _input = #"
0 VANGUARD 1
1 00005U 58002B 14242.42781498 .00000028 00000-0 24556-4 0 2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A 14245.43855606 .00000265 00000-0 95096-4 0 2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A 14245.36883128 .00001088 00000-0 12832-3 0 1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434
";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var regexObj =
new Regex(#"(?<=^\d+\s(?<name>[\w|\d|\s]+))\r\n(?<line1>(?<=^).*)\r\n(?<line2>(?<=^).*(?=\r))",
RegexOptions.Multiline);
Match matchResult = regexObj.Match(_input);
while (matchResult.Success)
{
string name = matchResult.Groups["name"].Value;
string line1 = matchResult.Groups["line1"].Value;
string line2 = matchResult.Groups["line2"].Value;
var regexObj1 = new Regex(#"(?<=^[1|2].*)([\d\w.-]+)");
Match matchResult1 = regexObj1.Match(line1);
var numbers1 = new List<string>();
while (matchResult1.Success)
{
string s = matchResult1.Value;
numbers1.Add(s);
matchResult1 = matchResult1.NextMatch();
}
var regexObj2 = new Regex(#"(?<=^[1|2].*)([\d\w.-]+)");
Match matchResult2 = regexObj2.Match(line2);
var numbers2 = new List<string>();
while (matchResult2.Success)
{
string s = matchResult2.Value;
numbers2.Add(s);
matchResult2 = matchResult2.NextMatch();
}
_satellites.Add(new Satellite
{
Name = name,
Line1 = line1,
Line2 = line2,
Numbers1 = numbers1,
Numbers2 = numbers2
});
matchResult = matchResult.NextMatch();
}
comboBox1.DataSource = _satellites;
comboBox1.DisplayMember = "Name";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var comboBox = (ComboBox) sender;
var satellites = comboBox.DataSource as List<Satellite>;
if (satellites != null && comboBox.SelectedIndex > -1)
{
Satellite selectedSatellite = satellites[comboBox.SelectedIndex];
Console.WriteLine("Selected satellite: " + selectedSatellite.Name);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox) sender;
string text = textBox.Text;
if (!string.IsNullOrWhiteSpace(text))
{
Satellite satellite =
_satellites.FirstOrDefault((s => s.Name.ToLower().StartsWith(text.ToLower())));
if (satellite != null)
{
Console.WriteLine("Found satellite: " + satellite);
}
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox) sender;
string text = textBox.Text;
if (!string.IsNullOrWhiteSpace(text))
{
Satellite satellite =
_satellites.FirstOrDefault(
s => s.Numbers1.Any(t => t.StartsWith(text)) || s.Numbers2.Any(t => t.StartsWith(text)));
if (satellite != null)
{
Console.WriteLine("Found satellite: " + satellite);
}
}
}
}
internal class Satellite
{
public string Name { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public List<string> Numbers1 { get; set; }
public List<string> Numbers2 { get; set; }
public override string ToString()
{
return string.Format("Name: {0}", Name);
}
}
}
Result:
If you don't want to use regex you could do something like this:
public List<string> GetSatelliteNames(string input)
{
string[] split = input.split(new string[2] { "\n", "\r\n" });
List<string> result = new List<string>();
foreach (var s in split)
{
string splitagain = s.split(new char[1] { ' ' });
if (s[0] == "0") result.add(s[1]);
}
return result;
}

Sorting and Storing in a Multidimensional Array List based on the data retrieved from a text file

I have stored the following information in text file. I am using the file stream and stream reader object to read it. I got an array method:
string[] MyArray = allText.Split(new string[]{" ",Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);
This is to store the entire content of a text file by splitting in terms of words.
How do i do the same thing and make the following data get stored in a multidimensional arraylist. By sorting it.
Princeton 12/12/2013 04:13PM
Leon 10/11/2013 05:13PM
Shawn 09/09/2013 04:00PM
Sandy 07/09/2012 09:00AM
Grumpy 18/09/2013 10:00AM
Visualize it like in tables. All this data is stored in a multidimensional array list.
Names have to be sorted and stored, date has to be sorted and stored and time has to be sorted and stored. Only the particular format in each given case is accepted.
This is what i tried but it keeps generating an error stating that the get and set methods have not been marked as extern or abstract and therefore must have a body.
using System;
using System.Collections;
using System.IO;
using System.Text;
class Planner
{ public string firstName { get; set;}
public string lastName { get; set; }
public DateTime dateTime { get; set; }
}
class exe
{
public static void Main(string[] args)
{
List<Planner> t = new List<Planner>();
StreamReader sr = new StreamReader("#cScheduler.txt"))
{
string line = string.Empty;
while ((line = sr.ReadLine()) != null)
{
string[] lines = line.Split(' ').ToArray();
//add to your list
t.Add(new Test() { firstName = lines[0], lastName = lines[1], dateTime = DateTime.ParseExact("MM/dd/yyyy hh:mm:ss tt",
lines[2] + lines[3],
CultureInfo.InvariantCulture) });
}
} //Your Ordered list now t = t.OrderBy(x => x.dateTime).ToList<Planner>();
}
}
I don't like multidimensional arrays - I'll use a List instead. It's got an array underneath anyway, so you can do as you please with it. ;)
List<string> lines = new List<string>();
foreach (var line in MyArray)
lines.Add(new List<string>()(line.Split(' ')); //feel free to change the .Split as needed
lines = lines.OrderBy(l => l[0]).ThenBy(l => l[1]).ThenBy(l => l[2]).ToList(); //will sort by name, then by date, then by time
There, lines should contain separated and sorted data. Note that the sorting is based on alphabetical sorting as everything is still being treated as a string. You can parse the data in the Linq query if you need to use specific types.
Of course from there you can parse the data (into actual string, DateTime and possibly TimeSpan instances) via appropriate classes or whatever else you need.
Here's the code you posted, corrected to work with the sample data you provided:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
class Planner
{
public string firstName { get; set; }
public DateTime dateTime { get; set; }
}
class exe
{
public static void Main(string[] args)
{
List<Planner> t = new List<Planner>();
using (StreamReader sr = new StreamReader("Scheduler.txt"))
{
string line = string.Empty;
while ((line = sr.ReadLine()) != null)
{
string[] lines = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
var planner = new Planner();
planner.firstName = lines[0];
var dateStr = String.Format("{0} {1}", lines[1], lines[2]);
var date = DateTime.ParseExact(dateStr, "dd/MM/yyyy hh:mmtt", System.Globalization.CultureInfo.InvariantCulture); //note the date format comes second. Also, in your examples days are first, months are second!
planner.dateTime = date;
t.Add(planner);
}
}
t = t.OrderBy(l => l.firstName).ThenBy(l => l.dateTime).ToList();
}
}
I don't know why you needed a lastName in your Planner class when it's never given in the examples... O_o

Formatting Twitter text (TweetText) with C#

Is there a better way to format text from Twitter to link the hyperlinks, username and hashtags? What I have is working but I know this could be done better. I am interested in alternative techniques. I am setting this up as a HTML Helper for ASP.NET MVC.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
namespace Acme.Mvc.Extensions
{
public static class MvcExtensions
{
const string ScreenNamePattern = #"#([A-Za-z0-9\-_&;]+)";
const string HashTagPattern = #"#([A-Za-z0-9\-_&;]+)";
const string HyperLinkPattern = #"(http://\S+)\s?";
public static string TweetText(this HtmlHelper helper, string text)
{
return FormatTweetText(text);
}
public static string FormatTweetText(string text)
{
string result = text;
if (result.Contains("http://"))
{
var links = new List<string>();
foreach (Match match in Regex.Matches(result, HyperLinkPattern))
{
var url = match.Groups[1].Value;
if (!links.Contains(url))
{
links.Add(url);
result = result.Replace(url, String.Format("{0}", url));
}
}
}
if (result.Contains("#"))
{
var names = new List<string>();
foreach (Match match in Regex.Matches(result, ScreenNamePattern))
{
var screenName = match.Groups[1].Value;
if (!names.Contains(screenName))
{
names.Add(screenName);
result = result.Replace("#" + screenName,
String.Format("#{0}", screenName));
}
}
}
if (result.Contains("#"))
{
var names = new List<string>();
foreach (Match match in Regex.Matches(result, HashTagPattern))
{
var hashTag = match.Groups[1].Value;
if (!names.Contains(hashTag))
{
names.Add(hashTag);
result = result.Replace("#" + hashTag,
String.Format("#{1}",
HttpUtility.UrlEncode("#" + hashTag), hashTag));
}
}
}
return result;
}
}
}
That is remarkably similar to the code I wrote that displays my Twitter status on my blog. The only further things I do that I do are
1) looking up #name and replacing it with Real Name;
2) multiple #name's in a row get commas, if they don't have them;
3) Tweets that start with #name(s) are formatted "To #name:".
I don't see any reason this can't be an effective way to parse a tweet - they are a very consistent format (good for regex) and in most situations the speed (milliseconds) is more than acceptable.
Edit:
Here is the code for my Tweet parser. It's a bit too long to put in a Stack Overflow answer. It takes a tweet like:
#user1 #user2 check out this cool link I got from #user3: http://url.com/page.htm#anchor #coollinks
And turns it into:
<span class="salutation">
To Real Name,
Real Name:
</span> check out this cool link I got from
<span class="salutation">
Real Name
</span>:
http://site.com/...
#coollinks
It also wraps all that markup in a little JavaScript:
document.getElementById('twitter').innerHTML = '{markup}';
This is so the tweet fetcher can run asynchronously as a JS and if Twitter is down or slow it won't affect my site's page load time.
I created helper method to shorten text to 140 chars with url included. You can set share length to 0 to exclude url from tweet.
public static string FormatTwitterText(this string text, string shareurl)
{
if (string.IsNullOrEmpty(text))
return string.Empty;
string finaltext = string.Empty;
string sharepath = string.Format("http://url.com/{0}", shareurl);
//list of all words, trimmed and new space removed
List<string> textlist = text.Split(' ').Select(txt => Regex.Replace(txt, #"\n", "").Trim())
.Where(formatedtxt => !string.IsNullOrEmpty(formatedtxt))
.ToList();
int extraChars = 3; //to account for the two dots ".."
int finalLength = 140 - sharepath.Length - extraChars;
int runningLengthCount = 0;
int collectionCount = textlist.Count;
int count = 0;
foreach (string eachwordformated in textlist
.Select(eachword => string.Format("{0} ", eachword)))
{
count++;
int textlength = eachwordformated.Length;
runningLengthCount += textlength;
int nextcount = count + 1;
var nextTextlength = nextcount < collectionCount ?
textlist[nextcount].Length :
0;
if (runningLengthCount + nextTextlength < finalLength)
finaltext += eachwordformated;
}
return runningLengthCount > finalLength ? finaltext.Trim() + ".." : finaltext.Trim();
}
There is a good resource for parsing Twitter messages this link, worked for me:
How to Parse Twitter Usernames, Hashtags and URLs in C# 3.0
http://jes.al/2009/05/how-to-parse-twitter-usernames-hashtags-and-urls-in-c-30/
It contains support for:
Urls
#hashtags
#usernames
BTW: Regex in the ParseURL() method needs reviewing, it parses stock symbols (BARC.L) into links.

Categories