I am trying to pull apart a string and get the text between two "#"'s. I have found ways to do it in Java and php and I am assuming they are similar in C#, i just jeep failing and pretty sure its PEBKAC. So I though I would ask.
Example- I want to programatically pull out "filenameid" and "Name" from this string:
'#filenameid#30day#Name#.xls'
Try splitting:
String source = "#filenameid#30day#Name#.xls";
String[] chunks = source
.Split(new Char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
then take appropriate chunks:
String id = chunks[0];
String period = chunks[1];
String name = chunks[2];
Use capturing groups.
#"#([^#]*)#"
Get the string you want from group index 1. Note that lookarounds won't work here.
If your string has same format always you can do the following:
string a = "#filenameid#30day#Name#.xls";
string[]split=a.Split('#');
string fileID = split[1];
string name = split[3];
You can achieve it using Regex.
void Main()
{
const string Expression = #"#([^#]*)*#";
const string TestSample = #"'#filenameid#30day#Name#.xls'";
Regex regex = new Regex(Expression);
regex.Matches(TestSample)
.Cast<Match>()
.Select(match => match.Captures[0].Value.Replace("#", ""))
.ToList()
.ForEach(Console.WriteLine);
}
Here is a low-level solution for the problem:
static void Main(string[] args) {
string text = "#filenameid#30day#Name#.xls";
int frameStart = 0;
int match = 0;
// loop on characters
for(int i = 0; i < text.Length; i++) {
char c = text[i];
switch(c) {
case '#':
// evaluate frame (text between meshes)
switch(match) {
// match at index 1
case 1:
Console.Write("filenameid=");
Console.WriteLine(text.Substring(frameStart, i - frameStart));
break;
// match at index 3
case 3:
Console.Write("name=");
Console.WriteLine(text.Substring(frameStart, i - frameStart));
break;
}
// move to next frame
frameStart = i + 1;
match++;
break;
}
}
// count of matches is match + 1
Console.ReadKey();
}
Related
Problem: I want to write a method that takes a message/index pair like this:
("Hello, I am *Name1, how are you doing *Name2?", 2)
The index refers to the asterisk delimited name in the message. So if the index is 1, it should refer to *Name1, if it's 2 it should refer to *Name2.
The method should return just the name with the asterisk (*Name2).
I have attempted to play around with substrings, taking the first delimited * and ending when we reach a character that isn't a letter, number, underscore or hyphen, but the logic just isn't setting in.
I know this is similar to a few problems on SO but I can't find anything this specific. Any help is appreciated.
This is what's left of my very vague attempt so far. Based on this thread:
public string GetIndexedNames(string message, int index)
{
int strStart = message.IndexOf("#") + "#".Length;
int strEnd = message.LastIndexOf(" ");
String result = message.Substring(strStart, strEnd - strStart);
}
If you want to do it the old school way, then something like:
public static void Main(string[] args)
{
string message = "Hello, I am *Name1, how are you doing *Name2?";
string name1 = GetIndexedNames(message, "*", 1);
string name2 = GetIndexedNames(message, "*", 2);
Console.WriteLine(message);
Console.WriteLine(name1);
Console.WriteLine(name2);
Console.ReadLine();
}
public static string GetIndexedNames(string message, string singleCharDelimiter, int index)
{
string valid = "abcdefghijlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
string[] parts = message.Split(singleCharDelimiter.ToArray());
if (parts.Length >= index)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < parts[index].Length; i++)
{
string character = parts[index].Substring(i, 1);
if (valid.Contains(character))
{
sb.Append(character);
}
else
{
return sb.ToString();
}
}
return sb.ToString();
}
return "";
}
You can try using regular expressions to match the names. Assuming that name is a sequence of word characters (letters or digits):
using System.Linq;
using System.Text.RegularExpressions;
...
// Either name with asterisk *Name or null
// index is 1-based
private static ObtainName(string source, int index) => Regex
.Matches(source, #"\*\w+")
.Cast<Match>()
.Select(match => match.Value)
.Distinct() // in case the same name repeats several times
.ElementAtOrDefault(index - 1);
Demo:
string name = ObtainName(
"Hello, I am *Name1, how are you doing *Name2?", 2);
Console.Write(name);
Outcome:
*Name2
Perhaps not the most elegant solution, but if you want to use IndexOf, use a loop:
public static string GetIndexedNames(string message, int index, char marker='*')
{
int lastFound = 0;
for (int i = 0; i < index; i++) {
lastFound = message.IndexOf(marker, lastFound+1);
if (lastFound == -1) return null;
}
var space = message.IndexOf(' ', lastFound);
return space == -1 ? message.Substring(lastFound) : message.Substring(lastFound, space - lastFound);
}
I have a very big string with a lot of usernames. I want to extract the names from the string. That means I have one big string with lot of names in it. At the end I want every username in a string array.
An example of the string:
blablablabla#User;\u0004User\username,blablablablablablablabla#User;\u0004User\anotherusername,#Viewblablablablablablablabla
Search for: u0004User\
Save all charractes until , is found in the string array
Pseudocode:
string [] array = new string []{};
int i = 0;
foreach (var c in bigdata)
{
if(c == "u0004User\")
{
array[i] = c.AllCharactersUntil(',');
i++;
//AllCharactersUntil is a pseudo function
}
}
You can use string.IndexOf to find the index of "u0004User\" then again to find the following comma. Then use string.Substring to get the name. Keeping track of the current index and using it to tell IndexOf where to start searching from.
string bigdata =
#"blablablabla#User;\u0004User\username,blablablablablablablabla#User;\u0004User\anotherusername,#Viewblablablablablablablabla";
string searchValue = #"u0004User\";
int index = 0;
List<string> names = new List<string>();
while (index < bigdata.Length)
{
index = bigdata.IndexOf(searchValue, index);
if (index == -1) break;
int start = index + searchValue.Length;
int end = bigdata.IndexOf(',', start);
if (end == -1) break;
names.Add(bigdata.Substring(start, end - start));
index = end + 1;
}
Console.WriteLine(string.Join(", ", names));
That will give you the following output
username, anotherusername
NOTE
I've assumed that the "\u0004" values are those 6 characters and not a single unicode character. If it is a unicode character then you need the following change
string searchValue = "\u0004User\\";
Here's a simple result:
string input = "blablablabla#User;\\u0004User\username,blablablablablablablabla#User;\\u0004User\anotherusername,#Viewblablablablablablablabla";
List<string> userNames = new List<string>();
foreach (Match match in Regex.Matches(input, #"(u0004User\\)(.*?),", RegexOptions.IgnoreCase))
{
string currentUserName = match.Groups[2].ToString();
userNames.Add(currentUserName); // Add UserName to List
}
I want to trim a string after a special character..
Lets say the string is str="arjunmenon.uking". I want to get the characters after the . and ignore the rest. I.e the resultant string must be restr="uking".
How about:
string foo = str.EverythingAfter('.');
using:
public static string EverythingAfter(this string value, char c)
{
if(string.IsNullOrEmpty(value)) return value;
int idx = value.IndexOf(c);
return idx < 0 ? "" : value.Substring(idx + 1);
}
you can use like
string input = "arjunmenon.uking";
int index = input.LastIndexOf(".");
input = input.Substring(index+1, input.Split('.')[1].ToString().Length );
Use Split function
Try this
string[] restr = str.Split('.');
//restr[0] contains arjunmenon
//restr[1] contains uking
char special = '.';
var restr = str.Substring(str.IndexOf(special) + 1).Trim();
Try Regular Expression Language
using System.IO;
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "arjunmenon.uking";
string pattern = #"[a-zA-Z0-9].*\.([a-zA-Z0-9].*)";
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine(match.Value);
if (match.Groups.Count > 1)
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups[ctr].Value);
}
}
}
Result:
arjunmenon.uking
Group 1: uking
Personally, I won't do the split and go for the index[1] in the resulting array, if you already know that your correct stuff is in index[1] in the splitted string, then why don't you just declare a constant with the value you wanted to "extract"?
After you make a Split, just get the last item in the array.
string separator = ".";
string text = "my.string.is.evil";
string[] parts = text.Split(separator);
string restr = parts[parts.length - 1];
The variable restr will be = "evil"
string str = "arjunmenon.uking";
string[] splitStr = str.Split('.');
string restr = splitStr[1];
Not like the methods that uses indexes, this one will allow you not to use the empty string verifications, and the presence of your special caracter, and will not raise exceptions when having empty strings or string that doesn't contain the special caracter:
string str = "arjunmenon.uking";
string restr = str.Split('.').Last();
You may find all the info you need here : http://msdn.microsoft.com/fr-fr/library/b873y76a(v=vs.110).aspx
cheers
I think the simplest way will be this:
string restr, str = "arjunmenon.uking";
restr = str.Substring(str.LastIndexOf('.') + 1);
What's the easiest and fastest way to find a sub-string(template) in a string and replace it with something else following the template's letter case (if all lower case - replace with lowercase, if all upper case - replace with uppercase, if begins with uppercase and so on...)
so if the substring is in curly braces
"{template}" becomes "replaced content"
"{TEMPLATE}" becomes "REPLACED CONTENT" and
"{Template}" becomes "Replaced content" but
"{tEMPLATE}" becomes "rEPLACED CONTENT"
Well, you could use regular expressions and a match evaluator callback like this:
regex = new Regex(#"\{(?<value>.*?)\}",
RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);
string replacedText = regex.Replace(<text>,
new MatchEvaluator(this.EvaluateMatchCallback));
And your evaluator callback would do something like this:
private string EvaluateMatchCallback(Match match) {
string templateInsert = match.Groups["value"].Value;
// or whatever
string replacedText = GetReplacementTextBasedOnTemplateValue(templateInsert);
return replacedText;
}
Once you get the regex match value you can just do a case-sensitive comparison and return the correct replacement value.
EDIT I sort of assumed you were trying to find the placeholders in a block of text rather than worry about the casing per se, if your pattern is valid all the time then you can just check the first two characters of the placeholder itself and that will tell you the casing you need to use in the replacement expression:
string foo = "teMPLATE";
if (char.IsLower(foo[0])) {
if (char.IsLower(foo[1])) {
// first lower and second lower
}
else {
// first lower and second upper
}
}
else {
if (char.IsLower(foo[1])) {
// first upper and second lower
}
else {
// first upper and second upper
}
}
I would still use a regular expression to match the replacement placeholder, but that's just me.
You can check the case of the first two letters of the placeholder and choose one of the four case transforming strategies for the inserted text.
public static string Convert(string input, bool firstIsUpper, bool restIsUpper)
{
string firstLetter = input.Substring(0, 1);
firstLetter = firstIsUpper ? firstLetter.ToUpper() : firstLetter.ToLower();
string rest = input.Substring(1);
rest = restIsUpper ? rest.ToUpper() : rest.ToLower();
return firstLetter + rest;
}
public static string Replace(string input, Dictionary<string, string> valueMap)
{
var ms = Regex.Matches(input, "{(\\w+?)}");
int i = 0;
var sb = new StringBuilder();
for (int j = 0; j < ms.Count; j++)
{
string pattern = ms[j].Groups[1].Value;
string key = pattern.ToLower();
bool firstIsUpper = char.IsUpper(pattern[0]);
bool restIsUpper = char.IsUpper(pattern[1]);
sb.Append(input.Substring(i, ms[j].Index - i));
sb.Append(Convert(valueMap[key], firstIsUpper, restIsUpper));
i = ms[j].Index + ms[j].Length;
}
return sb.ToString();
}
public static void DoStuff()
{
Console.WriteLine(Replace("--- {aAA} --- {AAA} --- {Aaa}", new Dictionary<string,string> {{"aaa", "replacement"}}));
}
Ended up doing that:
public static string ReplaceWithTemplate(this string original, string pattern, string replacement)
{
var template = Regex.Match(original, pattern, RegexOptions.IgnoreCase).Value.Remove(0, 1);
template = template.Remove(template.Length - 1);
var chars = new List<char>();
var isLetter = false;
for (int i = 0; i < replacement.Length; i++)
{
if (i < (template.Length)) isLetter = Char.IsUpper(template[i]);
chars.Add(Convert.ToChar(
isLetter ? Char.ToUpper(replacement[i])
: Char.ToLower(replacement[i])));
}
return new string(chars.ToArray());
}
How can the first letter in a text be set to capital?
Example:
it is a text. = It is a text.
public static string ToUpperFirstLetter(this string source)
{
if (string.IsNullOrEmpty(source))
return string.Empty;
// convert to char array of the string
char[] letters = source.ToCharArray();
// upper case the first char
letters[0] = char.ToUpper(letters[0]);
// return the array made of the new char array
return new string(letters);
}
It'll be something like this:
// precondition: before must not be an empty string
String after = before.Substring(0, 1).ToUpper() + before.Substring(1);
polygenelubricants' answer is fine for most cases, but you potentially need to think about cultural issues. Do you want this capitalized in a culture-invariant way, in the current culture, or a specific culture? It can make a big difference in Turkey, for example. So you may want to consider:
CultureInfo culture = ...;
text = char.ToUpper(text[0], culture) + text.Substring(1);
or if you prefer methods on String:
CultureInfo culture = ...;
text = text.Substring(0, 1).ToUpper(culture) + text.Substring(1);
where culture might be CultureInfo.InvariantCulture, or the current culture etc.
For more on this problem, see the Turkey Test.
If you are using C# then try this code:
Microsoft.VisualBasic.StrConv(sourceString, Microsoft.VisualBasic.vbProperCase)
I use this variant:
private string FirstLetterCapital(string str)
{
return Char.ToUpper(str[0]) + str.Remove(0, 1);
}
If you are sure that str variable is valid (never an empty-string or null), try:
str = Char.ToUpper(str[0]) + str[1..];
Unlike the other solutions that use Substring, this one does not do additional string allocations. This example basically concatenates char with ReadOnlySpan<char>.
I realize this is an old post, but I recently had this problem and solved it with the following method.
private string capSentences(string str)
{
string s = "";
if (str[str.Length - 1] == '.')
str = str.Remove(str.Length - 1, 1);
char[] delim = { '.' };
string[] tokens = str.Split(delim);
for (int i = 0; i < tokens.Length; i++)
{
tokens[i] = tokens[i].Trim();
tokens[i] = char.ToUpper(tokens[i][0]) + tokens[i].Substring(1);
s += tokens[i] + ". ";
}
return s;
}
In the sample below clicking on the button executes this simple code outBox.Text = capSentences(inBox.Text.Trim()); which pulls the text from the upper box and puts it in the lower box after the above method runs on it.
Take the first letter out of the word and then extract it to the other string.
strFirstLetter = strWord.Substring(0, 1).ToUpper();
strFullWord = strFirstLetter + strWord.Substring(1);
text = new String(
new [] { char.ToUpper(text.First()) }
.Concat(text.Skip(1))
.ToArray()
);
this functions makes capital the first letter of all words in a string
public static string FormatSentence(string source)
{
var words = source.Split(' ').Select(t => t.ToCharArray()).ToList();
words.ForEach(t =>
{
for (int i = 0; i < t.Length; i++)
{
t[i] = i.Equals(0) ? char.ToUpper(t[i]) : char.ToLower(t[i]);
}
});
return string.Join(" ", words.Select(t => new string(t)));;
}
string str = "it is a text";
// first use the .Trim() method to get rid of all the unnecessary space at the begining and the end for exemple (" This string ".Trim() is gonna output "This string").
str = str.Trim();
char theFirstLetter = str[0]; // this line is to take the first letter of the string at index 0.
theFirstLetter.ToUpper(); // .ToTupper() methode to uppercase the firstletter.
str = theFirstLetter + str.substring(1); // we add the first letter that we uppercased and add the rest of the string by using the str.substring(1) (str.substring(1) to skip the first letter at index 0 and only print the letters from the index 1 to the last index.)
Console.WriteLine(str); // now it should output "It is a text"
static String UppercaseWords(String BadName)
{
String FullName = "";
if (BadName != null)
{
String[] FullBadName = BadName.Split(' ');
foreach (string Name in FullBadName)
{
String SmallName = "";
if (Name.Length > 1)
{
SmallName = char.ToUpper(Name[0]) + Name.Substring(1).ToLower();
}
else
{
SmallName = Name.ToUpper();
}
FullName = FullName + " " + SmallName;
}
}
FullName = FullName.Trim();
FullName = FullName.TrimEnd();
FullName = FullName.TrimStart();
return FullName;
}
string Input = " it is my text";
Input = Input.TrimStart();
//Create a char array
char[] Letters = Input.ToCharArray();
//Make first letter a capital one
string First = char.ToUpper(Letters[0]).ToString();
//Concatenate
string Output = string.Concat(First,Input.Substring(1));
Try this code snippet:
char nm[] = "this is a test";
if(char.IsLower(nm[0])) nm[0] = char.ToUpper(nm[0]);
//print result: This is a test