Click here to Skip to main content
15,900,511 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to use Regex to parse a string such as the following;

#one# two *three*

And what I expect to get out of it is; 2 Matches = one and three

I've tried several patterns and they predictably return a single result;

#one# two *three*

What I have tried:

string str = "#one# two *three*";

This return nothing            
Regex r = new Regex(@"^[\#\*].*[\*\#]$");
Match m = r.Match(str);

This returns the above single result
Regex r = new Regex(@"^[\#\*].*[\*\#]$");
Match m = r.Match(str);


Additionally if anyone knows of a good beginner tutorial on Regex would appreciate a link.

Any help much appreciated!
Posted
Updated 17-Sep-22 3:28am
v3
Comments
Graeme_Grant 16-Sep-22 20:59pm    
I removed the WPF tag as RegEx has nothing to do with WPF.

If input= "#one# two *three* *four* #five# *six#"
and RegEx= "(\w+)"
Matches will be
one two three four five six


If input= "#one# two *three* *four* #five# *six#"
and RegEx= "[*#](\w+)[*#]"
Matches will be
one three four five six


If input= "#one# two *three* *four* #five# *six#"
and RegEx= "\*(\w+)\*|#(\w+)#"
Matches will be
one three four five


Just a few interesting links to help building and debugging RegEx.
Here is a link to RegEx documentation:
perlre - perldoc.perl.org[^]
Here is links to tools to help build RegEx and debug them:
.NET Regex Tester - Regex Storm[^]
Expresso Regular Expression Tool[^]
RegExr: Learn, Build, & Test RegEx[^]
Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript[^]
This one show you the RegEx as a nice graph which is really helpful to understand what is doing a RegEx: Debuggex: Online visual regex tester. JavaScript, Python, and PCRE.[^]
This site also show the Regex in a nice graph but can't test what match the RegEx: Regexper[^]
 
Share this answer
 
Comments
Graeme_Grant 17-Sep-22 9:31am    
Nice! +5
Patrice T 17-Sep-22 9:32am    
Thank you
Mike Hankey 17-Sep-22 9:41am    
Thanks Patrice
I have been using Expresso for many years.

The same result can be achieved by using Linq. This is more of a comment than a solution. But the comment section does not like code being posted in it.


C#
string str = "#one# two *three* *four* #five#";
var splitted = str.Split('#', '*');
var trimmed = splitted.Where((n, i) => (i % 2) != 0).Select(n => n);
foreach (var match in trimmed)
    Console.WriteLine(match.ToString());
 
Share this answer
 
Comments
Mike Hankey 17-Sep-22 9:41am    
Thanks George
Three things:
0) You don't want the ^ and $
1) Don't be greedy; try .*?
2) You want the delimiters to match, yes? @"(?'del'[#*])(?'val'.*?)\k'del'"
 
Share this answer
 
v2
regex101: build, test, and debug regex[^] is a good place to build and test your expressions. It supports many languages including C#.

The reason that you are only getting one result is because of this:
C#
Match m = r.Match(str);

Match is singular, Matches is plural.

Now, to the problem, this will return multiple results, also stripping the marking characters:
C#
string str = "#one# two *three*";

Regex r = new Regex(@"(?<=([#*]))(?:.)*?(?=\1)");
MatchCollection matches = r.Matches(str);

foreach (var match in matches)
	Console.WriteLine(match.ToString());


UPDATE:

For your next test, as per the comments below, you can use the following:
C#
string str = "#one# two *three* *four* #five#";

Regex r = new Regex(@"(?<=([#*]))(?:[a-zA-Z])*?(?=([#*]))");
MatchCollection matches = r.Matches(str);

foreach (var match in matches)
	Console.WriteLine(match.ToString());

Outputs:
one
three
four
five


As per regex101: build, test, and debug regex[^], the breakdown is as follows:
* Positive Lookbehind (?<=([#*]))
  - Match a single character present in the list below [#*]
    - #* matches a single character in the list #* (case sensitive)
* Non-capturing group (?:[a-zA-Z])*?
  - *? matches the previous token between zero and unlimited times,
       as few times as possible, expanding as needed (lazy)
  - Match a single character present in the list below [a-zA-Z]
* Positive Lookahead (?=([#*]))
  - Match a single character present in the list below [#*]
    - #* matches a single character in the list #* (case sensitive)
 
Share this answer
 
v4
Comments
George Swan 17-Sep-22 7:34am    
That works well. Do you think it could be adapted to handle multiple occurrences of the substrings like "#one# two *three* *four* #five#"?
Graeme_Grant 17-Sep-22 7:43am    
It is not limited to two results
George Swan 17-Sep-22 7:47am    
I have just run my example with your Regex and get : one
two *three* *four*
five
Graeme_Grant 17-Sep-22 8:12am    
see my update
George Swan 17-Sep-22 8:15am    
Excellent +5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900