I have a string and want to check if there is a letter(only one) that is surrounded by spaces. I tried using Regex but something is not right.
Console.Write("Write a string: ");
string s = Console.ReadLine();
string[] results = Regex.Matches(s, #" (a-zA-Z) ")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
I am not sure if I am doing this right I am new to C#
A full blown RegEx seems to be heavy stuff for such a simple operation.
This is a sample how to do it. It does include a lot of assumptions that might not be true for you (the fact that I don't consider start or end of string a valid whitespace, the fact I check for WhiteSpace instead of blank, you will have to check those assumptions I made).
namespace ConsoleApplication4
{
using System;
using System.Collections.Generic;
using System.Linq;
public static class StringExtensions
{
public static IEnumerable<int> IndexOfSingleLetterBetweenWhiteSpace(this string text)
{
return Enumerable.Range(1, text.Length-2)
.Where(index => char.IsLetter(text[index])
&& char.IsWhiteSpace(text[index + 1])
&& char.IsWhiteSpace(text[index - 1]));
}
}
class Program
{
static void Main()
{
var text = "This is a test";
var index = text.IndexOfSingleLetterBetweenWhiteSpace().Single();
Console.WriteLine("There is a single letter '{0}' at index {1}", text[index], index);
Console.ReadLine();
}
}
}
This should print
There is a single letter 'a' at index 8
Related
So, I have this basic program which matches a particular pattern in a string and then stores all the matches in an array. Then I append each matched element to a string.
Now my question is, how can I replace the matched pattern in the original string with the modified string that I generated based on my regex.
A sample working program can be found here: https://dotnetfiddle.net/UvgOVc
As you can see that the final string generated has the last modified string only. How can I replace the corresponding matches in the replacement?
Code:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
string url = "Please ab123456 this is and also bc789456 and also de456789 ";
string[] queryString = getMatch(url,#"\w{2}\d{6}");
string[] formatted=new string[10000];
string finalurl=string.Empty;
for(int i=0;i<queryString.Length;i++)
{
formatted[i]="replace "+queryString[i];
Console.WriteLine(formatted[i]+"\n");
finalurl=Regex.Replace(url,#"\w{2}\d{6}",formatted[i]);
}
Console.WriteLine(finalurl);
}
private static string[] getMatch(string text, string expr)
{
string matched=string.Empty;
string[] matches=new string[100];
var mc = Regex.Matches(text, expr);
if ( text != string.Empty && mc.Count > 0)
{
matches = mc.OfType<Match>()
.Select(x => x.Value)
.ToArray();
}
return matches;
}
}
Output:
replace ab123456
replace bc789456
replace de456789
Please replace de456789 this is and also replace de456789 and also replace de456789
Your code can be reduced to
string url = "Please ab123456 this is and also bc789456 and also de456789 ";
string[] queryString = Regex.Matches(url,#"\w{2}\d{6}").Cast<Match>().Select(x => x.Value).ToArray();
string finalurl=Regex.Replace(url,#"\w{2}\d{6}", "replace $&");
Console.WriteLine(finalurl); // => Please replace ab123456 this is and also replace bc789456 and also replace de456789
See the online C# demo.
Here, Regex.Matches(url,#"\w{2}\d{6}").Cast<Match>().Select(x => x.Value).ToArray() collects all matches into the queryString variable (if you need the match values array).
The Regex.Replace(url,#"\w{2}\d{6}", "replace $&") finds all matches of two word chars followed with six digits and appends replace + space before the matched texts (note $& is the backreference to the whole match value).
If you plan to perform some more manipulation with the found matches, consider using a match evaluator. Say, you defined SomeMethod(string s) somewhere, then you may use
string finalurl=Regex.Replace(url,#"\w{2}\d{6}", m =>
SomeMethod(m.Value);
);
I am trying to filter out the addressnumber of on inputstring, but the problem is my code yet leads to unwanted results when a string with multiple numbers comes in.
Is there a possibility to tell the Regex to filter into an array or something like that to recognize if there was more than one number in the original string?
String theNumbers = String.Join(String.Empty, Regex.Matches(inputString, #"\d+").OfType<Match>().Select(m => m.Value));
I tried it on a different way now aswell, but Regex.Split generates empty Strings in the Array and just filtering them out seems a bit hacky to me.
String[] extractedNumbersArray = Regex.Split(inputString, #"\D+");
Hope this helps (online):
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var inputString = "1 2 3";
var values = Regex
.Matches(inputString, #"(?<nr>\d+)")
.OfType<Match>()
.Select(m => m.Groups["nr"].Value)
.ToArray();
Console.WriteLine("Multipe numbers: " + (values.Length > 1 ? "yep" : "nope"));
foreach (var v in values)
{
Console.WriteLine(v);
}
}
}
I'm trying to see if an exact substring exists in a string array. It is returning true if the substring exists in the string but it will contains spelling errors.
EDIT:
For example if I am checking if 'Connecticut' exists in the string array but it is spelled 'Connecticute' it will still return true but I do not want it to. I want it to return false for 'Connecticute' and return true for
'Connecticut' only
Is there a way to do this using LINQ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string[] sample = File.ReadAllLines(#"C:\samplefile.txt");
/* Sample file containing data organised like
Niall Gleeson 123 Fake Street UNIT 63 Connecticute 00703 USA
*/
string[] states = File.ReadAllLines(#"C:\states.txt"); //Text file containing list of all US states
foreach (string s in sample)
{
if (states.Any(s.Contains))
{
Console.WriteLine("Found State");
Console.WriteLine(s);
Console.ReadLine();
}
else
{
Console.WriteLine("Could not find State");
Console.WriteLine(s);
Console.ReadLine();
}
}
}
}
}
String.Contains returns true if one part of the string is anywhere within the string being matched.
Hence "Conneticute".Contains("Conneticut") will be true.
If you want exact matches, what you're looking for is String.Equals
...
if (states.Any(s.Equals))
...
You could use \b to match word breaking characters (ie. white spaces, periods, start or end of string etc):
var r = new Regex("\bConneticut\b", RegexOptions.IgnoreCase);
var m = r.Match("Conneticute");
Console.WriteLine(m.Success); // false
Rather than using string.Contains, which matches whether the string contains the sequence of letters, use a regular expression match, with whatever you consider to be appropriate. For example, this will match on word boundaries,
var x = new [] { "Connect", "Connecticute is a cute place", "Connecticut", "Connecticut is a nice place" };
x.Dump();
var p = new Regex(#"\bConnecticut\b", RegexOptions.Compiled);
x.Where(s=>p.IsMatch(s)).Dump();
This will match "Connecticut" and "CConnecticut is a nice place" but not the other strings. Change the regex to suit your exact requirements.
(.Dump() is used in linqpad, which can be used to experiment with this sort of thing )
Assuming I have this input:
/green/blah/agriculture/apple/blah/
I'm only trying to capture and replace the occurrence of apple (need to replace it with orange), so I have this regex
var regex = new Regex("^/(?:green|red){1}(?:/.*)+(apple){1}(?:/.*)");
So I'm grouping sections of the input, but as non-capturing, and only capturing the one I'm concerned with. According to this $` will retrieve everything before the match in the input string, and $' will get everything after, so theoretically the following should work:
"$`Orange$'"
But it only retrieves the match ("apple").
Is it possible to do this with just substitutions and NOT match evaluators and looping through groups?
The issue is that apple can occur anywhere in that url scheme, hence an unknown number of capture groups.
Thanks.
To achieve what you want, I slightly changed your regex.
The new regex looks like this look for the updated version at the end of the answer:
What I am doing here is, I want all the other groups to become captured groups. Doing this I can use them as follow:
String replacement = "$1Orange$2";
string result = Regex.Replace(text, regex.ToString(), replacement);
I am using group 1,2 and 4 and in the middle of everything (where I suspect 'apple') I replace it with Orange.
A complete example looks like this:
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
String text = "/green/blah/agriculture/apple/blah/hallo/apple";
var regex = new Regex("^(/(?:green|red)/(?:[^/]+/)*?)apple(/.*)");
String replacement = "$1$2Orange$4";
string result = Regex.Replace(text, regex.ToString(), replacement);
Console.WriteLine(result);
}
}
And as well a running example is here
See the updated regex, I needed to change it again to capture things like this:
/green/blah/agriculture/apple/blah/hallo/apple/green/blah/agriculture/apple/blah/hallo/apple
With the above regex it matched the last apple and not the first as prio designated. I changed the regex to this:
var regex = new Regex("^(/(?:green|red)/(?:[^/]+/)*?)apple(/.*)");
I updated the code as well as the running example.
If you really want to replace only the first occurence of apple and dont mind about the URL structure then can you use one of the following methods:
First simply use apple as regex and use the overloaded Replace method.
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
String text = "/green/blah/agriculture/apple/blah/hallo/apple/green/blah/agriculture/apple/blah/hallo/apple";
var regex = new Regex(Regex.Escape("apple"));
String replacement = "Orange";
string result = regex.Replace(text, replacement.ToString(), 1);
Console.WriteLine(result);
}
}
See working Example
Second is the use of IndexOf and Substring which could be much quick as the use of the regex classes.
See the following Example:
class Program
{
static void Main(string[] args)
{
string search = "apple";
string text = "/green/blah/agriculture/apple/blah/hallo/apple/green/blah/agriculture/apple/blah/hallo/apple";
int idx = text.IndexOf(search);
int endIdx = idx + search.Length;
int secondStrLen = text.Length - endIdx;
if (idx != -1 && idx < text.Length && endIdx < text.Length && secondStrLen > -1)
{
string first = text.Substring(0, idx);
string second = text.Substring(endIdx, secondStrLen);
string result = first + "Orange" + second;
Console.WriteLine(result);
}
}
}
Working Example
In a WinForms textbox with multiple whitespaces (e.g. 1 1 A), where, between the 1s, there is whitespace, how could I detect this via the string methods or regex?
use IndexOf
if( "1 1a".IndexOf(' ') >= 0 ) {
// there is a space.
}
This function should do the trick for you.
bool DoesContainsWhitespace()
{
return textbox1.Text.Contains(" ");
}
int NumberOfWhiteSpaceOccurances(string textFromTextBox){
char[] textHolder = textFromTextBox.toCharArray();
int numberOfWhiteSpaceOccurances = 0;
for(int index= 0; index < textHolder.length; index++){
if(textHolder[index] == ' ')numberOfWhiteSpaceOccurances++;
}
return numberOfWhiteSpaceOccurances;
}
Not pretty clear what the problem is, but in case you just want a way to tell if there is a white space anywhere in a given string, a different solution to the ones proposed by the other stack users (which also work) is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(PatternFound("1 1 a"));
Console.WriteLine(PatternFound("1 1 a"));
Console.WriteLine(PatternFound(" 1 1 a"));
}
static bool PatternFound(string str)
{
Regex regEx = new Regex("\\s");
Match match = regEx.Match(str);
return match.Success;
}
}
}
in case what you want is determining whether a given succession of consecutive white spaces appear, then you will need to add more to the regex pattern string.
Refer to http://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx for the options.