C#, selecting certain parts from string - c#

In my example I have a string: "POINT (6.5976512883340064 53.011505757047068)"
What I would like is to extract the two doubles from that string and place them in separate strings.
I could use a StringReader, however the doubles are not fixed in length (aka the length may vary) so I can't state after which position to start selecting.
What I would like is to state that the first selection be made after the "(" and before the whitespace, and the second selection be made after the white space and before the ")". The rest of the string can be ignored.
Any suggestions?

void GetDoubles()
{
string valuesWithoutBrackets = ExtractStringBetweenBrackets("POINT (6.5976512883340064 53.011505757047068)");
string[] values = valuesWithoutBrackets.Split(" ".ToCharArray());
//values[0] = "6.5976512883340064"
//values[1] = "53.011505757047068"
}
string ExtractStringBetweenBrackets(string s)
{
// You should check for errors in real-world code, omitted for brevity
var startTag = "(";
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(")", startIndex);
return s.Substring(startIndex, endIndex - startIndex);
}

You can use the following code:
var str = "POINT (6.5976512883340064 53.011505757047068)";
var nums = Regex.Replace(a, #"POINT\s*\(([^)]+)\)", "$1").Split(' ');
var x = nums[0];
var y = nums[1];

var point = "POINT (6.5976512883340064 53.011505757047068)";
var indexOfFirstBrace = point.IndexOf('(') + 1;
var indexOfLastBrace = point.IndexOf(')');
var coordinates = point.Substring(indexOfFirstBrace, indexOfLastBrace - indexOfFirstBrace).Split(' ');
var xCoordinate = coordinates[0];
var yCoordinate = coordinates[1];

Related

List and array comparison

I have a requirement wherein I have a value in Viewbag.Keyword like "Johnson and Jen" so I have to split this value and compare it with List.
I was trying the below code but facing error some or the other way(eg; this is char not string and so on) and it doesn't look like smart coding as per latest functionalities available in framework 4.5
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
for (int j = 0; j < str1.Length;j++)
{
string str2 = Convert.ToString(str[j]);
if (result.Document.ContactName.IndexOf(str2,
StringComparison.CurrentCultureIgnoreCase) != -1)
Note: "ContactName" is string.
Please help with some latest code which improves performance.
You can use linq to check if result.Document.Name contains a word from array.
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
var names = str1.Where(x => (result.Document.ContactName.Contains(x))).ToList();
You can compare those names are on that string like below,
Remember comparison is case sensitive
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
if(str1.Any(result.Document.ContactName.Contains)){
//Do Something
}
Example -
var str = "Johnson and Jen";
string[] str1 = str.Split(' ');
string result = "Jendasdbnoahsdasnd"; // I assume your ContactName result is like this
if (str1.Any(result.Contains)) // This gives true because Jen in the string
{
//Do Something
}
But, for the string result = "jendasdbnoahsdasnd" it gives false because of the case.
If you need to check for the exact match of the words you get by splitting the keyword string using a white space against the contact name property from the collection then you can use a regular expression to do that.
The regular expression is of the form \bTheWordGoesHere\b where \b is the word boundary delimiter
Check this sample code snippet.
var keyword = "Johnson and Jen";
var arr = keyword.Split(' ');
var contactName = "Johnson anderson mobile";
for (var i = 0; i < arr.Length; i++)
{
var pattern = string.Format("\\b{0}\\b", arr[i]);
if (Regex.IsMatch(contactName, pattern, RegexOptions.IgnoreCase))
{
// do something
Console.WriteLine("contactName contains the word \"" + arr[i] + "\"");
}
}
rextester link
Below is a sample code for doing the same using clean code
var str = Convert.ToString(ViewBag.Keyword);
var possibleNames = str.split(' ');
//to check if any match exists
bool anyMatch = possibleNames.Any(n => n.Equals(result.Document.ContactName, StringComparison.InvariantCultureIgnoreCase));
//get matched names
var matchedNames = possibleNames.Where(n => n.Equals(result.Document.ContactName, StringComparison.InvariantCultureIgnoreCase));
//do whatever you want with matchedNames now
var array = matchedNames.ToArray();
var list = matchedNames.ToList();
You can split the string "Johnson and Jen" by using another string i.e. " and " this will exactly give you the names which will be appropriate to check against the contact name.
You can check about the Split function here and here
To check whether a property contains a specified string or not you can use the IndexOf method - a simple sample code snippet is given below, you can run this sample code snippet here.
var keyword = "Johnson and Jen";
var arr = keyword.Split(new string[] { " and " }, StringSplitOptions.None);
var contactName = "Johnson";
for (var i = 0; i < arr.Length; i++)
{
if (contactName.IndexOf(arr[i], StringComparison.OrdinalIgnoreCase) >= 0)
{
// do something
Console.WriteLine("contactName contains the string \"" + arr[i] + "\"");
}
}
The code snippet for your scenario would be as follows and in your code you don't need the unnecessary type casting i.e. string str2 = Convert.ToString(str[j]); because str[j] is already a string
var keyword = Convert.ToString(ViewBag.Keyword);
var arr = name.Split(new string[] { " and " }, StringSplitOptions.None);
for (int i = 0; i < arr.Length; i++)
{
if (result.Document.ContactName.IndexOf(arr[i], StringComparison.OrdinalIgnoreCase) != -1)
{
// do something
}
}
Using the StringComparison parameter with its value as StringComparison.OrdinalIgnoreCase will do a case insensitive search

how to fix error with Substring and IndexOf c#

i dont know how to fix this runtime error:
http://postimg.org/image/hh9vl7hi9/
The value of roomsInfo is : "#114|mag|nir|1||dan|nir|1||\0"
and it crash when the value is : "dan|nir|1||\0"
(in the second time of the while) when i try to do this line:
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));
this is the full code:
String roomsInfo = Program.sendToServ("#10||");
String[] room_name = new String[100];
String[] admin_name = new String[100];
String[] number_of_people = new String[100];
int check = 0, count = 0;
if(roomsInfo.IndexOf('\0') > 5)
{
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|')+1, roomsInfo.IndexOf('\0'));
while (roomsInfo[roomsInfo.IndexOf('|') + 2] != '\0' && roomsInfo[roomsInfo.IndexOf('|') + 1] != '\0') // #114|roomName1|RoomAdmin1|count1||roomName2|RoomAdmin2|count2||
{
if (check == 0)
{
room_name[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
check = 1;
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));
}
if (check == 1)
{
admin_name[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
check = 2;
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));
}
if (check == 2)
{
number_of_people[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
check = 0;
count++;
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 2, roomsInfo.IndexOf('\0'));
}
}
}
Thank you!
Nir
In order to Substring Correctly You must Get the length of substring Just like when you get length of Vector in Math.
for example you have two points in one line. say 5 and 13. To get the length between 5 and 13 you must subtract 5 from 13. so 13 - 5 = 8
int startIndex = roomsInfo.IndexOf('|') + 1;
int endIndex = roomsInfo.IndexOf('\0');
int length = endIndex - startIndex;
roomsInfo = roomsInfo.Substring(startIndex, length); // Will Get nir|1||
If you want to get the Last char too. you must add 1 to length
roomsInfo = roomsInfo.Substring(startIndex, length + 1); // Will Get nir|1||\0
From what i see in your code. your Substrings are All wrong. so you must do this to all of them.
One line solution
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0') - roomsInfo.IndexOf('|') - 1);
Again if you want to get last char too you must add 1 to the length.
I'm guessing that it might be something to do with the || between records (is that a record delimiter, I assume?) and your substring indexing.
What Glenn is saying would work to split a record into fields, but in your case all of your records are chained together and (I assume delimited by || ?) then finally terminated by a null zero. Therefore you would first need to split your string into set of records, before splitting the records into fields.
struct RoomInfo
{
public String RoomName;
public String AdminName;
public String WhatIsNir;
public int NumberOfPeople;
}
var roomsInfo = new List<RoomInfo>();
String allData = "#114|mag|nir|1||#115|dan|nir|1||\0".TrimEnd('\0');
String[] delimiters = new string[] { "||" };
String[] records = allData.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
foreach (var record in records)
{
String[] fields = record.Split('|');
roomsInfo.Add(new RoomInfo
{
RoomName = fields[0],
AdminName = fields[1],
WhatIsNir = fields[2],
NumberOfPeople = int.Parse(fields[3])
});
}
Another issue might be that your data and your fields are a mismatch. I.e. where do your three fields repeat in the following string? "#114|mag|nir|1||dan|nir|1||\0". I see four fields in that string, so I added one (room name) in the above example.
Of course, to use this solution is to say that there's a commitment to your data format. If this is something you are able to change (i.e. not determined by a 3rd party), then I would change it to something a little more standard. Even a basic form of CSV would be similar, but might be better.
Your implementation is extremely complex. It can be done with few lines of code, which is easier to maintain:
string roomsInfo = Program.sendToServ("#10||");
var room_name = new List<string>();
var admin_name = new List<string>();
var number_of_people = new List<string>();
if(roomsInfo.IndexOf('\0') > 5)
{
roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|')+1, roomsInfo.IndexOf('\0'));
var records = roomsInfo.Split(new[] {"||"}, StringSplitOptions.None);
foreach (var rec in records)
{
var fields = rec.Split(new [] {'|'}, StringSplitOptions.None);
room_name.Add(fields[0]);
admin_name.Add(fields[1]);
number_of_people.Add(fields[2]);
}
}
This can be improved, of course, in order to control exceptions.

How can i parse text from string and add it to a List<string> using indexof and substring?

The code:
int index = 0;
List<string> Names = new List<string>();
while (index != -1)
{
string firstTag = "a title";
string endTag = "href";
string forums = webBrowser1.DocumentText;
index = forums.IndexOf(firstTag);
int index1 = forums.IndexOf(endTag, index);
string Count = forums.Substring(index + 9, ((index1 - 35) - index));
Names.Add(forumsCount);
}
In this case i want to use indexof and substring.
The way i did it now i'm getting endless loop and very large List Names and all the Names inside is the same one the index is never move forward.
Looks like you never move forward the starting point. You need to use IndexOf(String, Int32) when getting the first index and specify where to start the search, otherwise you'll just keep getting the same result.
Something like this:
const string openingTag = "a title=\"";
const string closingTag = "\" href";
var html = " sadsffdaf a title=\"מכבי תאמכ\" href, a title=\" תאמכ\" href, a title=\"מכבי \" href";
var names = new List<string>();
var index = 0;
var previousIndex = 0;
while (index > -1)
{
index = html.IndexOf(openingTag, previousIndex);
if (index == -1)
continue;
var secondIndex = html.IndexOf(closingTag, index);
var result = html.Substring(index + openingTag.Length, secondIndex - (index + openingTag.Length));
names.Add(result);
previousIndex = index + 1;
}
EDIT: I updated code to include an example HTML string I tested against as per your comment.
I also updated the substring to get the text between the two tags. I assume this is what you want to do?
Also, in your question you're taking the first index from 'nums' and the second tag from 'forums'. I'm guessing this was a typo?
I'm not sure I can help any further without seeing the actual HTML you are parsing.

sub-strings replacements according to some mapping

Given a string, I need to replace substrings according to a given mapping. The mapping determines where to start the replacement, the length of text to be replaced and the replacement string. The mapping is according to the following scheme:
public struct mapItem
{
public int offset;
public int length;
public string newString;
}
For example: given a mapping {{0,3,"frog"},{9,3,"kva"}} and a string
"dog says gav"
we replace starting at position 0 a substring of the length 3 to the "frog", i.e.
dog - > frog
and starting the position 9 a substring of the length 3 to the "kva", i.e.
gav->kva
The new string becomes:
"frog says kva"
How can I do it efficiently?
You have to take care that replacements take into account the shift produced by preceding replacements. Also using a StringBuilder is more efficient, as is doesn't allocate new memory at each operation as string operations do. (Strings are invariant, which means that a completely new string is created at each string operation.)
var maps = new List<MapItem> { ... };
var sb = new StringBuilder("dog says gav");
int shift = 0;
foreach (MapItem map in maps.OrderBy(m => m.Offset)) {
sb.Remove(map.Offset + shift, map.Length);
sb.Insert(map.Offset + shift, map.NewString);
shift += map.NewString.Length - map.Length;
}
string result = sb.ToString();
The OrderBy makes sure that the replacements are executed from left to right. If you know that the mappings are provided in this order, you can drop the OrderBy.
Another simpler way is to begin with the replacements at the right end and work backwards, so that the character shifts do not alter the positions of not yet executed replacements:
var sb = new StringBuilder("dog says gav");
foreach (MapItem map in maps.OrderByDescending(m => m.Offset)) {
sb.Remove(map.Offset, map.Length);
sb.Insert(map.Offset, map.NewString);
}
string result = sb.ToString();
In case the mappings are already ordered in ascending order, a simple reverse for-statement seems appropriate:
var sb = new StringBuilder("dog says gav");
for (int i = maps.Count - 1; i >= 0; i--) {
MapItem map = maps[i];
sb.Remove(map.Offset, map.Length);
sb.Insert(map.Offset, map.NewString);
}
string result = sb.ToString();
You can write an Extension Method like below:
public static class ExtensionMethod
{
public static string ReplaceSubstringByMap(this string str, List<mapItem> map)
{
int offsetShift = 0;
foreach (mapItem mapItem in map.OrderBy(x => x.offset))
{
str = str.Remove(mapItem.offset + offsetShift, mapItem.length).Insert(mapItem.offset + offsetShift, mapItem.newString);
offsetShift += mapItem.newString.Length - mapItem.length;
}
return str;
}
}
And invoke it like below:
var map = new List<mapItem>
{
new mapItem
{
offset = 0,
length = 1,
newString = "frog"
},
new mapItem
{
offset = 9,
length = 1,
newString = "kva"
}
};
string str = "dog says gav";
var result = str.ReplaceSubstringByMap(map);

How can I parse a string into different strings in C#?

I just started work on a C# application. I need to break down a string into different parts. Is there an easy way to do this using C# patterns? I think I can do it with substrings but it might get messy and I want to do something that's easy to understand. Here's an example of the input:
AB-CDE-GHI-123-45-67-7777
variable1 = "AB-CDE-GHI"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
AB-CDE-GHIJKLM-123-45-67-7777
variable1 = "AB-CDE-GHIJKLM"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
AB-123-45-67-7777
variable1 = "AB"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
The first part of the string up until "123-45-67-7777" can be any length. Lucky for me the last part 123-45-67-7777 is always the same length and contains numbers that are zero padded.
I hope someone can come up with some suggestions for an easy method that uses regular expressions or something.
Input lines look like this:
aa-123-45-67-7777
HJHJH-123-45-67-7777
H-H-H--123-45-67-7777
222-123-45-67-7777
You do not need RegEx for parsing this kind of input.
You can use string.Split, in particular if the input is highly structured.
If you first split by - you will get a string[] with each part in a different index of the array.
The length property of the array will tell you how many parts you got and you can use that to reconstruct the parts you need.
You can rejoin any of the bit you need back.
string[] parts = "AB-CDE-GHI-123-45-67-7777".split('-');
// joining together the first 3 items:
string letters = string.Format("{0}-{1}-{2}", parts[0], parts[1], parts[2]);
// letters = "AB-CDE-GHI"
If the number of sections is variable (apart from the last 4), you can use the length in a loop to rebuild the wanted parts:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < parts.Length - 4; i++)
{
sb.FormatAppend("{0}-", parts[i]);
}
sb.Length = sb.Length - 1; // remove trailing -
If the last part is always a known length (14 characters) you could just do something like this:
var firstPart = inputLine.Substring(inputLine.Length - 14);
var secondPart = inputLine.Substring(0, inputLine.Length - 15); // 15 to exclude the last -
Then you can just do your string splitting and job done :)
Although it is possible to use here String.Split, a better solution, in my opinion, would be to tokenize the input and then parse it.
You can use tools such as ANTLR for this purpose.
string[] str = "AB-CDE-GHI-123-45-67-7777".Split('-')
int a = str.Length;
variable1="";
for(int i=0;i=<a-5;i++)
{
variable1=str[i]+"-"+variable1;
}
// last - remove
variable1 = variable1.Remove(variable1.Length-1,1);
variable2 = str[a-4]
variable3 = str[a-3]
variable4 = str[a-2]
variable5 = str[a-2]+"-"str[a-1];
like Oded say you can use string.Split
I edit my answer like you want
string[] tab = textBox1.Text.Split('-');
int length = tab.Length;
string var1 = string.Empty;
for(int i=0; i <= length-5 ; i++)
{
var1 = var1 + tab[i] + '-';
}
var1 = var1.Remove(var1.Length-1,1);
string var2 = tab[length-4];
string var3 = tab[length-3];
string var4 = tab[length-2];
string var5 = tab[length-2] + '-' + tab[length-1];
it's the same with the answer of #Govind KamalaPrakash Malviya just you have make var1 + tab[i]

Categories

Resources