Click here to Skip to main content
15,881,812 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.

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
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
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

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