How to replace text within a string based on their indices - c#

I have a string of text coming from a database. I also have a list of links from a database which have a start index and length correstponding to my string. I want to append the links within the text to be links
<a href=...
I.e
var stringText = "Hello look at http://www.google.com and this hello.co.uk";
This would have in the database
Link:http://www.google.com
Index:14
Length:21
Link:hello.co.uk
Index:45
Length:11
I eventually want
var stringText = "Hello look at http://www.google.com and this hello.co.uk";
There may be many links in the string, so I need a way of looping through these links and replacing based on the index and length. I would just loop through and replace based on the link (string.replace) but causes issues if there are the same link twice
var stringText = "www.google.com www.google.com www.google.com";
www.google.com would become a link and the second time would make the link within the link... a link.
I can obviously find the first index, but if I change it at that point, the index's are no longer valid.
Is there an easy way to do this or am I missing something?

You simply need to remove the subject from source using String.Remove, then use String.Insert to insert your replacement string.
As #hogan suggested in comments you need to sort the replacement list and do the replacement in reverse order (from last to first) to make it work.
If you need to perform many replacements in single string I recommend StringBuilder for performance reasons.

I would use regural expressions.
Take a look at this: Regular expression to find URLs within a string
It might help.

Here's solution without Remove or Insert, or regexes. Just addition.
string stringText = "Hello look at http://www.google.com and this hello.co.uk!";
var replacements = new [] {
new { Link = "http://www.google.com", Index = 14, Length = 21 },
new { Link = "hello.co.uk", Index = 45, Length = 11 } };
string result = "";
for (int i = 0; i <= replacements.Length; i++)
{
int previousIndex = i == 0 ? 0 : replacements[i - 1].Index + replacements[i - 1].Length;
int nextIndex = i < replacements.Length ? replacements[i].Index : replacements[i - 1].Index + replacements[i - 1].Length + 1;
result += stringText.Substring(previousIndex, nextIndex - previousIndex);
if (i < replacements.Length)
{
result += String.Format("{1}", replacements[i].Link,
stringText.Substring(replacements[i].Index, replacements[i].Length));
}
}

Related

Sorting a given string - What is wrong with my IF Contains block?

Super new to C# apologize upfront. My goal is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. Numbers can be from 1 to 9. So 1 will be the first word (not 0).
My plan of attack is to split the string, having one variable of int data-type (int lookingForNum) and the other variable turning that into a String data-type(string stringLookingForNum), then for each loop over the array looking to see if any elements contain string stringLookingForNum, if they do I add it to an emptry string variable, lastly add 1 to int variable lookingForNum. My issue seems to be with the if statement with the Contains method. It will not trigger the way I currently have it written. Hard coding in if (word.Contains("1")) will trigger that code block but running it as written below will not trigger the if statement.Please can anyone tell my WHY!?!? I console.log stringLookingForNum and it is for sure a string data type "1"
This noobie would appreciate any help. Thanks!
string testA = "is2 Thi1s T4est 3a"; //--> "Thi1s is2 3a T4est"
string[] arrayTestA = testA.Split(' ');
string finalString = string.Empty;
int lookingForNum = 1; //Int32
foreach (string word in arrayTestA){
string stringLookingForNum = lookingForNum.ToString();
//Don't understand why Contains is not working as expected here)
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
}
lookingForNum++;
}
you need this - look for the string with 1, the look for the string with 2 etc. Thats not what you are doing
you look at the first string and see if it contains one
then look at the second one and see if it contains 2
....
int lookingForNum = 1;
while(true){ // till the end
string stringLookingForNum = lookingForNum.ToString();
bool found = false;
foreach (string word in arrayTestA){
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
found = true;
break;
}
}
if(!found) break;
lookingForNum++;
}
To sort you should simply use OrderBy, and since you need to sort by number inside a word - just Find and extract a number from a string
string testA = "is2 Thi1s T4est 3a";
var result = testA.Split().OrderBy(word =>
Int32.Parse(Regex.Match(word, #"\d+").Value));
Console.WriteLine(string.Join(" ", result));

counting a string with special characters in a string in c#

I would like to count a string (search term) in another string (logfile).
Splitting the string with the method Split and searching the array afterwards is too inefficient for me, because the logfile is very large.
In the net I found the following possibility, which worked quite well so far. However,
count = Regex.Matches(_editor.Text, txtLookFor.Text, RegexOptions.IgnoreCase).Count;
I am now running into another problem there, that I get the following error when I count a string in the format of "Nachricht erhalten (".
Errormessage:
System.ArgumentException: "Nachricht erhalten (" analysed - not enough )-characters.
You need to escape the ( symbol as it has a special function in regular expressions:
var test = Regex.Matches("Nachricht erhalten (3)", #"Nachricht erhalten \(", RegexOptions.IgnoreCase).Count;
If you do this by user input where the user is not familiar with regular expressions you probably easier off using IndexOf in a while loop, where you keep using the new index found in the last loop. Which might also be a bit better on performance than a regular expression. Example:
var test = "This is a test";
var searchFor = "is";
var count = 0;
var index = test.IndexOf(searchFor, 0);
while (index != -1)
{
++count;
index = test.IndexOf(searchFor, index + searchFor.Length);
}

How to get second value via c# StartsWith() method

string text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
How to get how many times the text **David Diaz occurs in the string text?
UPDATED MY QUESTION
By using StartWhith you can check if the string starts whit ** if it is take the first two words of the string whits will represent the name
string text = "**David Diaz He went to school.";
if (text.StartsWith("**"))
{
var names = text.Split(' ')
.Take(2)
.ToArray();
var fullName = names[0] + " " + names[1];
}
UPDATE
As you said in the commend you want to look how many David Diaz occurs in one string, you can use regex for that.
string text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
int matches = Regex.Matches(
text,
#"(?:\S+\s)?\S*David Diaz\S*(?:\s\S+)?",
RegexOptions.IgnoreCase
).Count;
var text = "Today is a good day for help. **David Diaz He went to school. **David Diaz like apple. ";
var pos = 0;
var num = 0;
var search = "**David Diaz";
while ((pos = text.IndexOf(search, pos)) > -1)
{
num ++;
pos += search.Length;
}
Console.WriteLine(num);
you can try out this in dotnetfiddle
Updated Answer:
It sounds like you want to find the number of times a substring exists in your text. For that, you'll want to use RegEx.Matches, as explained in this answer: https://stackoverflow.com/a/3016577/682840
or LINQ, as explained in this answer: https://stackoverflow.com/a/541994/682840
Original Answer:
.StartsWith returns true/false if the string begins with the search string you provide. If you're wanting to know where a substring exists within your text, you'll need to use .IndexOf or a Regular Expression for more advanced scenarios.
IndexOf will return the location in the text where your provided search string starts (or -1 if it isn't found).

Unable to Split the string accordingly

I know this question would have been asked infinite number of times, but I'm kinda stuck.
I have a string something like
"Doc1;Doc2;Doc3;12"
it can be something like
"Doc1;Doc2;Doc3;Doc4;Doc5;56"
Its like few pieces of strings separated by semicolon, followed by a number or id.
I need to extract the number/id and the strings separately.
To be exact, I can have 2 strings: one having "Doc1;Doc2;Doc3" or "Doc1;Doc2;Doc3;Doc4" and the other having just the number/id as "12" or "34" or "45" etc.
And yeah I am using C# 3.5
I understand its a pretty easy and witty question, but this guy is stuck.
Assistance required from experts.
Regards
Anurag
string.LastIndexOf and string.Substring are the keys to what you're trying to do.
var str = "Doc1;Doc2;Doc3;12";
var ind = str.LastIndexOf(';');
var str1 = str.Substring(0, ind);
var str2 = str.Substring(ind+1);
One way:
string[] tokens = str.Split(';');
var docs = tokens.Where(s => s.StartsWith("Doc", StringComparison.OrdinalIgnoreCase));
var numbers = tokens.Where(s => s.All(Char.IsDigit));
String docs = s.Substring(0, s.LastIndexOf(';'));
String number = s.Substring(s.LastIndexOf(';') + 1);
One possible approach would be this:
var ids = new List<string>();
var nums = new List<string>();
foreach (var s in input.Split(';'))
{
int val;
if (!int.TryParse(s, out val)) { ids.Add(s); }
else { nums.Add(s); }
}
where input is something like Doc1;Doc2;Doc3;Doc4;Doc5;56. Now, ids will house all of the Doc1 like values and nums will house all of the 56 like values.
you can use StringTokenizer functionality.
http://www.c-sharpcorner.com/UploadFile/pseabury/JavaLikeStringTokenizer11232005015829AM/JavaLikeStringTokenizer.aspx
split string using ";"
StringTokenizer st = new StringTokenizer(src1,";");
collect final String. that will be your ID.
You may try one of two options: (assuming your input string is in string str;
Approach 1
Get LastIndexOf(';')
Split the string based on the index. This will give you string and int part.
Split the string part and process it
Process the int part
Approach 2
Split the string on ;
Run a for loop - for (int i = 0; i < str.length - 2; i++) - this is the string part
Process str[length - 1] separately - this is the int part
Please take this as a starting point as there could be other approaches to implement a solution for this
string actual = "Doc1;Doc2;Doc3;12";
int lstindex = actual.LastIndexOf(';');
string strvalue = actual.Substring(0, lstindex);
string id = actual.Substring(lstindex + 1);

Remove characters after specific character in string, then remove substring?

I feel kind of dumb posting this when this seems kind of simple and there are tons of questions on strings/characters/regex, but I couldn't find quite what I needed (except in another language: Remove All Text After Certain Point).
I've got the following code:
[Test]
public void stringManipulation()
{
String filename = "testpage.aspx";
String currentFullUrl = "http://localhost:2000/somefolder/myrep/test.aspx?q=qvalue";
String fullUrlWithoutQueryString = currentFullUrl.Replace("?.*", "");
String urlWithoutPageName = fullUrlWithoutQueryString.Remove(fullUrlWithoutQueryString.Length - filename.Length);
String expected = "http://localhost:2000/somefolder/myrep/";
String actual = urlWithoutPageName;
Assert.AreEqual(expected, actual);
}
I tried the solution in the question above (hoping the syntax would be the same!) but nope. I want to first remove the queryString which could be any variable length, then remove the page name, which again could be any length.
How can I get the remove the query string from the full URL such that this test passes?
For string manipulation, if you just want to kill everything after the ?, you can do this
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.IndexOf("?");
if (index >= 0)
input = input.Substring(0, index);
Edit: If everything after the last slash, do something like
string input = "http://www.somesite.com/somepage.aspx?whatever";
int index = input.LastIndexOf("/");
if (index >= 0)
input = input.Substring(0, index); // or index + 1 to keep slash
Alternately, since you're working with a URL, you can do something with it like this code
System.Uri uri = new Uri("http://www.somesite.com/what/test.aspx?hello=1");
string fixedUri = uri.AbsoluteUri.Replace(uri.Query, string.Empty);
To remove everything before the first /
input = input.Substring(input.IndexOf("/"));
To remove everything after the first /
input = input.Substring(0, input.IndexOf("/") + 1);
To remove everything before the last /
input = input.Substring(input.LastIndexOf("/"));
To remove everything after the last /
input = input.Substring(0, input.LastIndexOf("/") + 1);
An even more simpler solution for removing characters after a specified char is to use the String.Remove() method as follows:
To remove everything after the first /
input = input.Remove(input.IndexOf("/") + 1);
To remove everything after the last /
input = input.Remove(input.LastIndexOf("/") + 1);
Here's another simple solution. The following code will return everything before the '|' character:
if (path.Contains('|'))
path = path.Split('|')[0];
In fact, you could have as many separators as you want, but assuming you only have one separation character, here is how you would get everything after the '|':
if (path.Contains('|'))
path = path.Split('|')[1];
(All I changed in the second piece of code was the index of the array.)
The Uri class is generally your best bet for manipulating Urls.
To remove everything before a specific char, use below.
string1 = string1.Substring(string1.IndexOf('$') + 1);
What this does is, takes everything before the $ char and removes it. Now if you want to remove the items after a character, just change the +1 to a -1 and you are set!
But for a URL, I would use the built in .NET class to take of that.
Request.QueryString helps you to get the parameters and values included within the URL
example
string http = "http://dave.com/customers.aspx?customername=dave"
string customername = Request.QueryString["customername"].ToString();
so the customername variable should be equal to dave
regards
I second Hightechrider: there is a specialized Url class already built for you.
I must also point out, however, that the PHP's replaceAll uses regular expressions for search pattern, which you can do in .NET as well - look at the RegEx class.
you can use .NET's built in method to remove the QueryString.
i.e., Request.QueryString.Remove["whatever"];
here whatever in the [ ] is name of the querystring which you want to
remove.
Try this...
I hope this will help.
You can use this extension method to remove query parameters (everything after the ?) in a string
public static string RemoveQueryParameters(this string str)
{
int index = str.IndexOf("?");
return index >= 0 ? str.Substring(0, index) : str;
}

Categories

Resources