Replacing only single "\n" in string occurrence - c#

I have a string in C# which can have multiple \n characters. For e.g. :
string tp = "Hello\nWorld \n\n\n !!";
If there is a single occurrence of \n I want to replace it with something, but if more than one \n appear together in the same place I want to leave them alone. So for the tp string above I want to replace the \n between Hello and World, because there is only one at that place, and leave the the three \n nearer the end of the string alone, because they appear in a group.
If I try to use the Replace() method in C# it replaces all of them. How can I resolve this issue?

You can try using regular expressions: let's change \n into "*" whenever \n is single:
using System.Text.RegularExpressions;
...
string tp = "Hello\nWorld \n\n\n !!";
// "Hello*World \n\n\n !!";
string result = Regex.Replace(tp, "\n+", match =>
match.Value.Length > 1
? match.Value // multiple (>1) \n in row: leave intact
: "*"); // single ocurrence: change into "*"

A solution using loops:
char[] c = "\t"+ tp + "\t".ToCharArray();
for(int i = 1; i < c.Length - 1; i++)
if(c[i] == '\n' && c[i-1] != '\n' && c[i+1] != '\n')
c[i] = 'x';
tp = new string(c, 1, c.Length-2);

Use regular expressions and combine negative lookbehind and lookahead:
var test = "foo\nbar...foo\n\nbar\n\n\nfoo\r\nbar";
var replaced = System.Text.RegularExpressions.Regex.Replace(test, "(?<!\n)\n(?!\n)", "_");
// only first and last \n have been replaced
While searching through the input the regex "stops" at any "\n" it finds and verifies if no "\n" is one character behind the current position or ahead.
Thus only single "\n" will be replaced.

Related

C# Get line of multiline String starting with specific word

I have a multiline string, say
abcde my first line
fghij my second line
klmno my third line
All of this is one String, but what I want to do now is to get the content (substring) of this string which is starting with a specific word, for example "fghij". So if I do a method and pass "fghij" to it, it should return me "fghij my second line" in that case.
The following I tried, but it does not work, unfortunately m.Success is always false:
String getLineBySubstring(String myInput, String mySubstring)
{
Match m = Regex.Match(myInput, "^(" + mySubstring + "*)", RegexOptions.Multiline);
Console.WriteLine("getLineBySubstring operation: " + m.Success);
if (m.Success == true)
{
return m.Groups[0].Value;
}
else
{
return "NaN";
}
}
The * operator is currently quantifying the last letter in mySubstring. You need to precede the operator with . to eat up the rest of the characters on the given line. No need for grouping either.
Match m = Regex.Match(myInput, "^" + mySubstring + ".*", RegexOptions.Multiline);
if (m.Success) {
// return m.Value
}
Ideone Demo
You are almost there, just change the * char to [^\r\n]+
Match m = Regex.Match(myInput, "^(" + mySubstring + "[^\n\r]+)", RegexOptions.Multiline);
[^\r\n]+ will match any character, but \r and \n, which are used to mark a new line.
Try to add line ending $ to your regex. Also * concatenated to mySubstring specifies repeat of the last symbol in mySubstring, you should have .* to catch all the possible ones.
Regex.Match(myInput, "^(" + mySubstring + ".*)$", RegexOptions.Multiline);
If you need to check that string starts with some substring, then you should avoid Regex. Just split whole string to lines and check each line with StartsWith.
String getLineBySubstring(String myInput, String mySubstring)
{
string[] lines = myInput.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
if (line.StartsWith(mySubstring))
return line;
return "NaN";
}

C# replace string except when preceded by another

I want to replace all ocurrence of " by \" in a string except if this " is preceded by a \
for exemple the string hello "World\" will become hello \"World\"
Is it possible without using regex ?
But if I have to use regex, what kind have I to use ?
Thanks for help,
regards,
You could use a lookbehind:
var output = Regex.Replace(input, #"(?<!\\)""", #"\""")
Or you could just make the preceeding character optional, for example:
var output = Regex.Replace(input, #"\\?""", #"\""")
This works because " is replaced with \" (which is what you wanted), and \" is replaced with \", so no change.
The regex for this would be:
(?<!\\)"
Without a regex this should do:
yourStringVar.Replace("""","\\""").Replace("\\\\""","\\""");
It is possible without using regex:
str = str.Replace(" \"", "\\\"");
Since you have asked if it's possible without using regex explicitly, that's not as simple and impossible with pure String.Replace approaches. You could use a loop and a StringBuilder:
StringBuilder builder = new StringBuilder();
builder.Append(text[0] == '"' ? "\\\"" : text.Substring(0, 1));
for (int i = 1; i < text.Length; i++)
{
Char next = text[i];
Char last = text[i - 1];
if (next == '"' && last != '\\')
builder.Append("\\\"");
else
builder.Append(next);
}
string result = builder.ToString();
Edit: here's a demo (difficult to create that string literal): http://ideone.com/Xmeh1w

split string multiple characters without space C#

I have a field that is displayed inside a div and the problem is that it doesn't break line if a user puts in a string thats longer then the number of characters that can fit outside the line within a div, it basically stretches outside the div. How can I insert a space in every word 'thats in a string' that has a seuqence of 20 characters or more without a space between . For example, now I am doing something like this
string words
Regex.Replace(words, "(.{" + 20 + "})", "$1" + Environment.NewLine);
But that just inserts a line break at every 20 character oppose to a sequence without a space. I am really not that good with regular expressions so the code above is something I found.
Would a CSS solution work better?
word-wrap:break-word;
example:
http://jsfiddle.net/45Fq4/
To solve this with regex you could use #"(\S{20})" as your pattern.
\S will match any non-whitespace character which I believe fits your criteria since it will then only work if it finds 20 or more non-whitespace characters in a row.
Example usage is:
string words = "It should break after \"t\": abcdefghijklmnopqrstuvwxyz";
string output = Regex.Replace(words, #"(\S{20})", "$1" + Environment.NewLine);
this code worked for me:
string words
string outputwords = words;
int CharsWithoutSpace = 0;
for (int i = 0; i < outputwords.Length; i++)
{
if (outputwords[i] == ' ')
{
CharsWithoutSpace = 0;
}
else
{
CharsWithoutSpace++;
if (CharsWithoutSpace >= 20)
{
outputwords = outputwords.Insert(i + 1, Environment.NewLine);
CharsWithoutSpace = 0;
}
}
}
Console.WriteLine(outputwords);

How to find the number of occurrences of a letter in only the first sentence of a string?

I want to find number of letter "a" in only first sentence. The code below finds "a" in all sentences, but I want in only first sentence.
static void Main(string[] args)
{
string text; int k = 0;
text = "bla bla bla. something second. maybe last sentence.";
foreach (char a in text)
{
char b = 'a';
if (b == a)
{
k += 1;
}
}
Console.WriteLine("number of a in first sentence is " + k);
Console.ReadKey();
}
This will split the string into an array seperated by '.', then counts the number of 'a' char's in the first element of the array (the first sentence).
var count = Text.Split(new[] { '.', '!', '?', })[0].Count(c => c == 'a');
This example assumes a sentence is separated by a ., ? or !. If you have a decimal number in your string (e.g. 123.456), that will count as a sentence break. Breaking up a string into accurate sentences is a fairly complex exercise.
This is perhaps more verbose than what you were looking for, but hopefully it'll breed understanding as you read through it.
public static void Main()
{
//Make an array of the possible sentence enders. Doing this pattern lets us easily update
// the code later if it becomes necessary, or allows us easily to move this to an input
// parameter
string[] SentenceEnders = new string[] {"$", #"\.", #"\?", #"\!" /* Add Any Others */};
string WhatToFind = "a"; //What are we looking for? Regular Expressions Will Work Too!!!
string SentenceToCheck = "This, but not to exclude any others, is a sample."; //First example
string MultipleSentencesToCheck = #"
Is this a sentence
that breaks up
among multiple lines?
Yes!
It also has
more than one
sentence.
"; //Second Example
//This will split the input on all the enders put together(by way of joining them in [] inside a regular
// expression.
string[] SplitSentences = Regex.Split(SentenceToCheck, "[" + String.Join("", SentenceEnders) + "]", RegexOptions.IgnoreCase);
//SplitSentences is an array, with sentences on each index. The first index is the first sentence
string FirstSentence = SplitSentences[0];
//Now, split that single sentence on our matching pattern for what we should be counting
string[] SubSplitSentence = Regex.Split(FirstSentence, WhatToFind, RegexOptions.IgnoreCase);
//Now that it's split, it's split a number of times that matches how many matches we found, plus one
// (The "Left over" is the +1
int HowMany = SubSplitSentence.Length - 1;
System.Console.WriteLine(string.Format("We found, in the first sentence, {0} '{1}'.", HowMany, WhatToFind));
//Do all this again for the second example. Note that ideally, this would be in a separate function
// and you wouldn't be writing code twice, but I wanted you to see it without all the comments so you can
// compare and contrast
SplitSentences = Regex.Split(MultipleSentencesToCheck, "[" + String.Join("", SentenceEnders) + "]", RegexOptions.IgnoreCase | RegexOptions.Singleline);
SubSplitSentence = Regex.Split(SplitSentences[0], WhatToFind, RegexOptions.IgnoreCase | RegexOptions.Singleline);
HowMany = SubSplitSentence.Length - 1;
System.Console.WriteLine(string.Format("We found, in the second sentence, {0} '{1}'.", HowMany, WhatToFind));
}
Here is the output:
We found, in the first sentence, 3 'a'.
We found, in the second sentence, 4 'a'.
You didn't define "sentence", but if we assume it's always terminated by a period (.), just add this inside the loop:
if (a == '.') {
break;
}
Expand from this to support other sentence delimiters.
Simply "break" the foreach(...) loop when you encounter a "." (period)
Well, assuming you define a sentence as being ended with a '.''
Use String.IndexOf() to find the position of the first '.'. After that, searchin a SubString instead of the entire string.
find the place of the '.' in the text ( you can use split )
count the 'a' in the text from the place 0 to instance of the '.'
string SentenceToCheck = "Hi, I can wonder this situation where I can do best";
//Here I am giving several way to find this
//Using Regular Experession
int HowMany = Regex.Split(SentenceToCheck, "a", RegexOptions.IgnoreCase).Length - 1;
int i = Regex.Matches(SentenceToCheck, "a").Count;
// Simple way
int Count = SentenceToCheck.Length - SentenceToCheck.Replace("a", "").Length;
//Linq
var _lamdaCount = SentenceToCheck.ToCharArray().Where(t => t.ToString() != string.Empty)
.Select(t => t.ToString().ToUpper().Equals("A")).Count();
var _linqAIEnumareable = from _char in SentenceToCheck.ToCharArray()
where !String.IsNullOrEmpty(_char.ToString())
&& _char.ToString().ToUpper().Equals("A")
select _char;
int a =linqAIEnumareable.Count;
var _linqCount = from g in SentenceToCheck.ToCharArray()
where g.ToString().Equals("a")
select g;
int a = _linqCount.Count();

Replace char in a string

how to change
XXX#YYY.ZZZ into XXX_YYY_ZZZ
One way i know is to use the string.replace(char, char) method,
but i want to replace "#" & "." The above method replaces just one char.
one more case is what if i have XX.X#YYY.ZZZ...
i still want the output to look like XX.X_YYY_ZZZ
Is this possible?? any suggestions thanks
So, if I'm understanding correctly, you want to replace # with _, and . with _, but only if . comes after #? If there is a guaranteed # (assuming you're dealing with e-mail addresses?):
string e = "XX.X#YYY.ZZZ";
e = e.Substring(0, e.IndexOf('#')) + "_" + e.Substring(e.IndexOf('#')+1).Replace('.', '_');
Here's a complete regex solution that covers both your cases. The key to your second case is to match dots after the # symbol by using a positive look-behind.
string[] inputs = { "XXX#YYY.ZZZ", "XX.X#YYY.ZZZ" };
string pattern = #"#|(?<=#.*?)\.";
foreach (var input in inputs)
{
string result = Regex.Replace(input, pattern, "_");
Console.WriteLine("Original: " + input);
Console.WriteLine("Modified: " + result);
Console.WriteLine();
}
Although this is simple enough to accomplish with a couple of string Replace calls. Efficiency is something you will need to test depending on text size and number of replacements the code will make.
You can use the Regex.Replace method:
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace(v=VS.90).aspx
You can use the following extension method to do your replacement without creating too many temporary strings (as occurs with Substring and Replace) or incurring regex overhead. It skips to the # symbol, and then iterates through the remaining characters to perform the replacement.
public static string CustomReplace(this string s)
{
var sb = new StringBuilder(s);
for (int i = Math.Max(0, s.IndexOf('#')); i < sb.Length; i++)
if (sb[i] == '#' || sb[i] == '.')
sb[i] = '_';
return sb.ToString();
}
you can chain replace
var newstring = "XX.X#YYY.ZZZ".Replace("#","_").Replace(".","_");
Create an array with characters you want to have replaced, loop through array and do the replace based off the index.
Assuming data format is like XX.X#YYY.ZZZ, here is another alternative with String.Split(char seperator):
string[] tmp = "XX.X#YYY.ZZZ".Split('#');
string newstr = tmp[0] + "_" + tmp[1].Replace(".", "_");

Categories