I am trying to use substring to get a value from a string as such:
surname='Smith',name="John"
I basically want to use the text "name" and the quotes to get the value "John"..
Is there a way to do this please?
you could use linq query to get name
var query = #"surname='Smith',name = \""John\""";
var name = query
.Split(',')
.Select(s => new KeyValuePair<string, string>(
s.Split('=').GetValue(0).ToString().Trim(),
s.Split('=').GetValue(1).ToString().Trim()
))
.FirstOrDefault(kvp => kvp.Key == "name").Value;
Console.WriteLine(name);
There are many ways to do that.
That is one:
char[] quotes = { '\'', '\"' };
string input = "surname='Smith',name=\"John\"";
string[] sections = input.Split(',');
for (int i = 0; i < sections.Length; i++)
{
string[] pair = sections[i].Split('=');
if (pair[0] == "surname")
Debug.WriteLine("surname=" + pair[1].Trim(quotes));
if (pair[0] == "name")
Debug.WriteLine("name=" + pair[1].Trim(quotes));
}
Related
could you help splitting a string into key value pairs around the colon delimiter. I am having trouble with this.
eg.
"somekey:value1 value2 another:<value3 one_more:value4..value5"
output
<"somekey", "value1 value2">
<"another", "<value3">
<"one_more", "value4..value5">
This if you just want a simple conversion. you can also use regex.
private static Dictionary<string, string> Dictionary(string str)
{
var dictionary = new Dictionary<string, string>();
var splitOnSpace = str.Split(" ");
var value = string.Empty;
var key = "";
var i = 0;
while (i < splitOnSpace.Length)
{
var item = splitOnSpace[i];
if (item.Contains(":"))
{
var split = item.Split(':');
key = split[0];
value = split[1];
dictionary.Add(key, value);
}
else
{
value += " " + item;
dictionary[key] = value;
}
i++;
}
return dictionary;
}
The regex extracting such key-value pairs is
([^\s:]+):(.*?)(?=\s+[^\s:]+:|$)
(Demo)
The tricky part here is (?=\s+[^\s:]+:|$) lookahead, which tells the "match anything for value" regex ((.*?)) stop as soon as it encounters the next key preceded by some spaces (\s+[^\s:]+:) or simply end of string ($).
Then the match groups can be extracted as follows:
var input = "somekey:value1 value2 another:<value3 one_more:value4..value5";
var matches = Regex.Matches(input, #"([^\s:]+):(.*?)(?=\s+[^\s:]+:|$)");
var pairs = matches.Select(m => (m.Groups[1].Value, m.Groups[2].Value));
foreach (var (key, value) in pairs)
{
Console.WriteLine($"<\"{key}\": \"{value}\">");
}
Full demo
You can try this regex.
string givenString =
#"key1:value1 value2 key2:<value3 key3:value4..value5";
Dictionary<string, string> result1 = Regex
.Split(givenString, "([a-z0-9]+:)")
.Skip(1) // will skip the first empty
.Select((item, index) => new {
value = item.Trim(),
index = index / 2
})
.GroupBy(item => item.index)
.ToDictionary(chunk => chunk.First().value.TrimEnd(':'),
chunk => chunk.Last().value);
I have this list
var allPlaces = new[]
{
new { Name = "Red apple", OtherKnownNames = "Green" },
new { Name = "Orange", OtherKnownNames = "" },
new { Name = "Banana", OtherKnownNames = "the" },
}.ToList();
my query is "the apple"
my code does not return me first and third item, query has 2 words separated by a space, I want if any word in query starts with the Name or OtherKnownName should be returned.
var query = "the apple";
var queryParts = query.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var filteredList =
allPlaces
.Where(p =>
p.Name
.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.Any(pp => queryParts.Any(qp => qp.StartsWith(pp)))
|| p.OtherKnownNames
.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.Any(pp => queryParts.Any(qp => qp.StartsWith(pp))))
.ToList();
Assuming you want to ignore case, and accept names that match the beginning of query words (based on your example with StartsWith).
Use an extension method to make splitting without empty entries nicer:
public static string[] SplitNoEmpty(this string s, params char[] seps) => s.Split(seps, StringSplitOptions.RemoveEmptyEntries);
You can simply split up the query string and search for matches:
var qwords = query.SplitNoEmpty(' ');
var ans = allPlaces.Where(p => qwords.Any(qw => (p.Name + " " + p.OtherKnownNames).SplitNoEmpty(' ')
.Any(nw => qw.StartsWith(nw, StringComparison.CurrentCultureIgnoreCase))
)
)
.ToList();
So I have multiple arrays of strings. Within each array I have a string which uses '|' as a separator. What I need is to create a string with the first elements of the array up until the '|'.
So in the example I need 6485,6486,6487,6509,6510,6511,6533,6534,6535,|
Use String.Split() to split the original strings, then store the first ones in a separate array, then use String.Join() to concatenate them
string[] tempStrings = new string[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
tempStrings[i] = stringArray[i].Split(#"|")[0];
}
string result = String.Join(",", tempStrings);
Using System.Linq :
string[] temp = new string[] { "1,2,3|4,5,6|7,8,9", "10,11,12|13,14,15", "16,17,18"};
var result = String.Join(",", temp.Select(x => x.Split('|').FirstOrDefault())
.ToList());
With null and empty values :
string[] temp = new string[] { "1,2,3|4,5,6|7,8,9", "10,11,12|13,14,15", "16,17,18", "", null };
var result = String.Join(",", temp.Select(x => x?.Split('|').FirstOrDefault())
.Where(x => !string.IsNullOrWhiteSpace(x))
.ToList());
How do I modify the index number from an array to have a preceding 0 for number 1 - 9.
However, I would like numbers 10 on up to remain the same.
This is the raw data from debugging when getting my data from the tb1.text
"1ABC\r\n2ABC\r\3ABC\r\4ABC\r\n5ABC"
This is how I would like to store the data in my localDB.
"01ABC\r\n02ABC\r\03ABC\r\04ABC\r\n...10ABC"
Here is what I have so far.
var lines = tb1.Text.Split('\n').Select((line, index) => "YRZ"+(index + 01) + line).ToArray();
var res = string.Join("\n", lines);
Since the indexes are already part of the data entered, you need to either read it from there (and use that index) or remove it from there (and use the index you can get while Selecting). You can parse it using a regular expression. Once you have the index isolated, you can use .ToString("00") to add a leading zero.
var regex = new Regex(#"^(\d+)(.*)$");
var result = string.Join("\r\n",
tb1.Text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var m = regex.Match(x);
return int.Parse(m.Groups[1].Value).ToString("00") + m.Groups[2].Value;
}));
Debug.Assert("01ABC\r\n02ABC\r\n03ABC\r\n04ABC\r\n10ABC" == result);
If you only want 0 in the string why not updating it as a string:
var text = "1ABC\r\n2ABC\r\n3ABC\r\n4ABC\r\n5ABC";
var lines = text.Split('\n').ToList();
var withZero = lines.Select(
(line, i) =>
{
var newVal = i < 9 ? string.Format("0{0}", line) : line;
return newVal;
});
var result = string.Join("\n", withZero);
Or in a more concise form:
var result = string.Join("\n", text.Split('\n').Select(
(line, i) =>
{
var newVal = i < 9 ? string.Format("0{0}", line) : line;
return newVal;
}));
I need to sort a List<string> by comparing the list with a string
for example:
I have a List that contains the following Items.
Kaboki
kriiki
Kale
Kutta
Kiki
Kicki
Krishna
Kseaki
The search keyword is ki I need to sort the list items using the keyword in such a way that, the strings that match in the string start have should be first and the string having the matched string in the other position have to be in the last
Here is my current code
public static List<string> GetLocations(string prefixText)
{
try
{
DataTable dtlocs = (DataTable) HttpContext.Current.Session["locations"];
var dValue = from row in dtlocs.AsEnumerable()
where row.Field<string>("Location_Name").ToLower().Contains(prefixText.ToLower())
select row.Field<string>("Location_Name");
var results = dValue.OrderBy(s => s.IndexOf(prefixText, StringComparison.Ordinal));
var str = new List<string>(results.ToList());
if (!str.Any())
str.Add("No locations found");
return str;
}
catch (Exception)
{
var str = new List<string> {"No locations found"};
return str;
}
}
Here I'm able to get the first matched values to the top but cannot sort the remaining values
and I have another issue. there is a word King Koti and i'm searhing for Ko and this word comes to first.I think this happens because, the string has two sub strings and one of the substrings start with the matched word.
and can I make the matched letters to bold ??
var res = list.OrderBy(y=> !y.StartsWith("Ki", StringComparison.OrdinalIgnoreCase))
.ThenBy(x => x)
OrderBy orders false before true:
var result = list.OrderBy(s => !s.StartsWith("ki", StringComparison.OrdinalIgnoreCase))
.ThenBy(s => !s.ToLower().Contains("ki"));
I think this should work:
list = (from str in list
let idx = str.IndexOf(keyword, StringComparison.OrdinalIgnoreCase)
let change = idx != 0 ? idx : int.MinValue
orderby change
select str).ToList();
You can use a combination of Linq's OrderBy and the IndexOf methods:
var input = ...
var search = "ki";
var results = input.Select(Value => new { Value, Index = s.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) })
.Where(pair => pair.Index >= 0)
.OrderBy(pair => pair.Index)
.Select(pair => pair.Value);
Or in query syntax:
var results =
from s in input
let i = s.IndexOf(search, StringComparison.InvariantCultureIgnoreCase)
where i >= 0
orderby i
select s;