I have a string with text inside curlies like this:
{field1}-{field}+{field3}Anthing{field4}
from which I need to get an array like this:
['field1', 'field2', 'field3', 'field4']
Is there a way to do it using regexes in c#?
You can use Split and Linq:
string[] words = s.Split('+')
.Select(word => word.Substring(1, word.Length - 2))
.ToArray();
Or, you can match for {...} tokens using a simple regular expression:
MatchCollection matches = Regex.Matches(s, #"\{(\w*)\}");
string[] words = matches.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
\w* would only match alphanumeric characters, you may want to replace it with [^}]* or .*?.
like this ? ↓
static void Main(string[] args)
{
string from = "{field1}+{field2}+{field3}";
string[] to = from.Split("{}+".ToCharArray() , StringSplitOptions.RemoveEmptyEntries).ToArray();
foreach (var x in to)
Console.WriteLine(x);
Console.ReadKey();
}
FOR EDIT
To solve the problem with "{field1}-{field}+{field3}Anthing{field4} "
static void Main(string[] args)
{
string f = "{field1}-{field}+{field3}Anthing{field4} ";
List<string> lstPattern = new List<string>();
foreach (Match m in Regex.Matches(f, "{.*?}"))
{
lstPattern.Add(m.Value.Replace("{","").Replace("}",""));
}
foreach (var p in lstPattern)
Console.WriteLine(p);
}
Related
I need to recover each number in a glued string
For example, from these strings:
string test = "number1+3"
string test1 = "number 1+4"
I want to recover (1 and 3) and (1 and 4)
How can I do this?
CODE
string test= "number1+3";
List<int> res;
string[] digits= Regex.Split(test, #"\D+");
foreach (string value in digits)
{
int number;
if (int.TryParse(value, out number))
{
res.Add(number)
}
}
This regex should work
string pattern = #"\d+";
string test = "number1+3";
foreach (Match match in Regex.Matches(test, pattern))
Console.WriteLine("Found '{0}' at position {1}",
match.Value, match.Index);
Note that if you intend to use it multiple times, it's better, for performance reasons, to create a Regex instance than using this static method.
var res = new List<int>();
var regex = new Regex(#"\d+");
void addMatches(string text) {
foreach (Match match in regex.Matches(text))
{
int number = int.Parse(match.Value);
res.Add(number);
}
}
string test = "number1+3";
addMatches(test);
string test1 = "number 1+4";
addMatches(test1);
MSDN link.
Fiddle 1
Fiddle 2
This calls for a regular expression:
(\d+)\+(\d+)
Test it
Match m = Regex.Match(input, #"(\d+)\+(\d+)");
string first = m.Groups[1].Captures[0].Value;
string second = m.Groups[2].Captures[0].Value;
An alternative to regular expressions:
string test = "number 1+4";
int[] numbers = test.Replace("number", string.Empty, StringComparison.InvariantCultureIgnoreCase)
.Trim()
.Split("+", StringSplitOptions.RemoveEmptyEntries)
.Select(x => Convert.ToInt32(x))
.ToArray();
I have string variable that has value like this
string hello = "Endpoint: Efficacy, Intervene: Single Group, Mask: Open, Purpose: Treatment";
As I am extracting from XML so Endpoint , Intervene , Mask and Purpose remains
same but its value can change.
I want to store this Endpoint , intervene , mask and purpose separately in different variables any help will be much appreciated.
var result = hello.Split(',')
.Select(part => part.Split(':'))
.ToDictionary(split => split[0], split => split[1].Trim());
Try this way using Dictionary
string hello = "Endpoint: Efficacy, Intervene: Single Group, Mask: Open, Purpose: Treatment";
Dictionary<string, string> result = new Dictionary<string, string>();
var s1 = hello.Split(',');
foreach (var s in s1)
{
var v = s.Split(':');
result.Add(v[0].Trim(), v[1].Trim());
}
After that you can get result using key value of the Dictionary
foreach (var a in result)
{
Console.WriteLine(a.Key +" " + a.Value);
}
Split your string first by , and then by : and save the result in dictionary:
public class Program
{
public static void Main(string[] args)
{
string hello = "Endpoint: Efficacy, Intervene: Single Group, Mask: Open, Purpose: Treatment";
string[] arr = hello.Split(',');
Dictionary<string, string> result = new Dictionary<string, string>();
foreach(string s in arr)
{
string[] keyValuePair = s.Split(':');
result[keyValuePair[0].Replace(" ","")] = keyValuePair[1].Replace(" ","");
}
foreach(var v in result)
{
Console.WriteLine(v.Key + " : " + v.Value );
}
}
}
If the pattern is fixed, this can help you.
string hello = "Endpoint: Efficacy, Intervene: Single Group, Mask: Open, Purpose: Treatment";
string[] packs = hello.Split(',');
var data = packs.ToDictionary(k => k.Split(':').First().Trim(), v => v.Split(':').Last().Trim());
I came up with something more dynamic just in case someone have to deal with variable keywords to match.
This first extracts the keywords and builds a pattern to match. Matches are then captured by name and each capture group is named after a keyword so that we can access them by keyword:
var input = "Endpoint: Efficacy, Intervene: Single Group, Mask: Open, Purpose: Treatment";
//extract keywords: (word followed by ':' )
var keywords = Regex.Matches( input, #"(\w*):" ).Cast<Match>()
.Select( m => m.Groups[ 1 ].Value );
//build the pattern to match (create capture groups named as keywords)
var pattern = String.Join( ", ", keywords.Select(
k => k + $#": (?<{k}>(\w*\s*)*)" ) );
var matches = Regex.Matches( input, pattern );
//access groups by keyword
foreach( var keyword in keywords )
Console.WriteLine( matches[ 0 ].Groups[ keyword ].Value );
I have string pattern like this:
#c1 12,34,222x8. 45,989,100x10. 767x55. #c1
I want to change these patterns into this:
c1,12,8
c1,34,8
c1,222,8
c1,45,10
c1,989,10
c1,100,10
c1,767,55
My code in C#:
private void btnProses_Click(object sender, EventArgs e)
{
String ps = txtpesan.Text;
Regex rx = new Regex("((?:\d+,)*(?:\d+))x(\d+)");
Match mc = rx.Match(ps);
while (mc.Success)
{
txtpesan.Text = rx.ToString();
}
}
I've been using split and replace but to no avail. After I tried to solve this problem, I see many people using regex, I tried to use regex but I do not get the logic of making a pattern regex.
What should I use to solve this problem?
sometimes regex is not good approach - old school way wins. Assuming valid input:
var tokens = txtpesan.Text.Split(' '); //or use split by regex's whitechar
var prefix = tokens[0].Trim('#');
var result = new StringBuilder();
//skip first and last token
foreach (var token in tokens.Skip(1).Reverse().Skip(1).Reverse())
{
var xIndex = token.IndexOf("x");
var numbers = token.Substring(0, xIndex).Split(',');
var lastNumber = token.Substring(xIndex + 1).Trim('.');
foreach (var num in numbers)
{
result.AppendLine(string.Format("{0},{1},{2}", prefix, num, lastNumber));
}
}
var viola = result.ToString();
Console.WriteLine(viola);
And here comes a somewhat ugly regex based solution:
var q = "#c1 12,34,222x8. 45,989,100x10. 767x55. #c1";
var results = Regex.Matches(q, #"(?:(?:,?\b(\d+))(?:x(\d+))?)+");
var caps = results.Cast<Match>()
.Select(m => m.Groups[1].Captures.Cast<Capture>().Select(cap => cap.Value));
var trailings = results.Cast<Match>().Select(m => m.Groups[2].Value).ToList();
var c1 = q.Split(' ')[0].Substring(1);
var cnt = 0;
foreach (var grp in caps)
{
foreach (var item in grp)
{
Console.WriteLine("{0},{1},{2}", c1, item, trailings[cnt]);
}
cnt++;
}
The regex demo can be seen here. The pattern matches blocks of comma-separated digits while capturing the digits into Group 1, and captures the digits after x into Group 2. Could not get rid of the cnt counter, sorry.
I have to write a program which parses a string for words starting with '#' and return the words along with the # symbol.
I have tried something like:
char[] delim = { '#' };
string[] strArr = commenttext.Split(delim);
return strArr;
But it returns all the words without '#' in an array.
I need something pretty straight forward.No LINQ like things
If the string is "abc #ert #xyz" then I should get back #ert and #xyz.
If you define "word" as "separated by spaces" then this would work:
string[] strArr = commenttext.Split(' ')
.Where(w => w.StartsWith("#"))
.ToArray();
If you need something more complex, a Regular Expression might be more appropriate.
I need something pretty straight forward.No LINQ like things>
The non-Linq equivalent would be:
var words = commenttext.Split(' ');
List<string> temp = new List<string>();
foreach(string w in words)
{
if(w.StartsWith("#"))
temp.Add(w);
}
string[] strArr = temp.ToArray();
If you're against using Linq, which you should not be unless you're required to use older .NET versions, an approach along these lines would suit your needs.
string[] words = commenttext.Split(delimiter);
for (int i = 0; i < words.Length; i++)
{
string word = words[i];
if (word.StartsWith(delimiter))
{
// save in array / list
}
}
const string test = "#Amir abcdef #Stack #C# mnop xyz";
var splited = test.Split(' ').Where(m => m.StartsWith("#")).ToList();
foreach (var b in splited)
{
Console.WriteLine(b.Substring(1, b.Length - 1));
}
Console.ReadKey();
How can I get numbers between brackets of this text with regex in C#?
sample text :
"[1]Ali ahmadi,[2]Mohammad Razavi"
result is : 1,2
My C# code is :
string result = null;
string[] digits = Regex.Split(Text, #"[\d]");
foreach (string value in digits)
{
result += value + ",";
}
return result.Substring(0,result.Length - 1);
string s = "[1]Ali ahmadi,[2]Mohammad Razavi";
Regex regex = new Regex(#"\[(\d+)\]", RegexOptions.Compiled);
foreach (Match match in regex.Matches(s))
{
Console.WriteLine(match.Groups[1].Value);
}
This will capture the numbers between brackets (\d+), and store them in the first matched group (Groups[1]).
DEMO.
Using a Linq-based approach on João's answer:
string s = "[1]Ali ahmadi,[2]Mohammad Razavi";
var digits = Regex.Matches(s, #"\[(\d+)\]")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();
foreach (var match in digits)
{
Console.WriteLine(match);
}
DEMO