Reputation: 1469
I'm trying to write a regex to match the following text:
f
, s
or t
f
, s
or t
This is the regex I've come up with: (f|s|t)(\d+(f|s|t))*
, but it doesn't seem to work.
Input: f20s30t
Expected matches:
Actual matches:
f
30t
t
Why is my regex expression wrong?
Edit: I'm using this method to split the input.
Upvotes: 1
Views: 295
Reputation: 48711
In regex world (f|s|t)
is equal to [fst]
but has a few downsides in comparison. So use latter (a character class) in place of former. Using split
method you could split on this:
(?<=[fts])(?=\d+[fts])
Above regex matches a position where a character from [fts]
meets an occurrence of digits following a character from [fts]
. This (?<=...)
is a positive look-behind and (?=...)
constructs a positive look-ahead.
Code (see demo here):
string input = "f20s30t";
string pattern = @"(?<=[fts])(?=\d+[fts])";
string[] substrings = Regex.Split(input, pattern);
foreach (string match in substrings)
{
Console.WriteLine("{0}", match);
}
Output:
f
20s
30t
Upvotes: 1
Reputation: 3474
Going by your example code:
^([fst]|[0-9]+[fst])$
^
: start of string[fst]
: one of f
, s
or t
|
: OR[0-9]+
: one or more digits[fst]
: one of f
, s
or t
$
: end of stringIn C#:
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string input = "f20s30t";
string pattern = "([fst]|[0-9]+[fst])";
string[] substrings = Regex.Split(input, pattern);
foreach (string match in substrings)
{
Console.WriteLine("'{0}'", match);
}
}
}
//
//f
//
//20s
//
//30t
Upvotes: 1
Reputation: 626748
Since you are using C#, you may match a string with a pattern and access the capture collection of each repeated capturing group:
var s = "f20s30t";
var m = Regex.Match(s, @"^([fst])(\d+[fst])*$");
if (m.Success)
{
Console.WriteLine(m.Groups[1].Value);
foreach (var g in m.Groups[2].Captures.Cast<Capture>().Select(t => t.Value))
Console.WriteLine(g);
}
The advantage of this approach is that it also validates the string, and you won't get results for a string like TEXT random f20s30t here....
.
See the C# demo, output
f
20s
30t
Here is the regex demo:
Details
^
- start of the string([fst])
- Capturing group 1: f
, s
or t
(\d+[fst])*
- 0 or more repetitions (captured into Group 2 with each value saved in the group stack) of:
\d+
- 1+ digits[fst]
- f
, s
or t
$
- end of string.Upvotes: 1