I have created a method where I can search for string placeholders, this I do with Regular expressions.
At the moment I try to expand this method by adding grouping features.
For example if I have this string:
"Hallo {g:test1} asdasd {p:test1} sdfsdf{o:test1}"
I want to :
Search for the string test1, even if there is standing a letter:(like g:) before it.
I want to search for: all strings with for example a g: before it.
I can't really figure out how to do this in C# can someone help me?
At the moment I programmed this:
private string test() {
string pattern = #"\{(.*?)\}";
string query = "Hallo {g:test1} asdasd {p:test1} sdfsdf{o:test1}";
var matches = Regex.Matches(query, pattern);
foreach (Match m in matches) {
Test = m.Groups[1].Value;
}
return Test;
}
Try this:
\{(?:.:)?(.*?)\}
It will match the text not including the letter and the colon which may be before it.
To limit this to strings with a particular letter before it:
\{(?:#:)(.*?)\} replacing # with the letter you are filtering on
e.g.
\{(?:g:)(.*?)\}
\{.:test1\}
\{g:.+?\}
Related
I am trying to learn some .net6 and c# and I am struggling with regular expressions a lot. More specificaly with Avalonia in Windows if that is relevant.
I am trying to do a small app with 2 textboxes. I write text on one and get the text "filtered" in the other one using a value converter.
I would like to filter math expressions to try to solve them later on. Something simple, kind of a way of writing text math and getting results real time.
I have been trying for several weeks to figure this regular expression on my own with no success whatsoever.
I would like to replace in my string "_Expression{BLABLA}" for "BLABLA". For testing my expressions I have been checking in http://regexstorm.net/ and https://regex101.com/ and according to them my matches should be correct (unless I misunderstood the results). But the results in my little app are extremely odd to me and I finally decided to ask for help.
Here is my code:
private static string? FilterStr(object value)
{
if (value is string str)
{
string pattern = #"\b_Expression{(.+?)\w*}";
Regex rgx = new(pattern);
foreach (Match match in rgx.Matches(str))
{
string aux = "";
aux = match.Value;
aux = Regex.Replace(aux, #"_Expression{", "");
aux = Regex.Replace(aux, #"[\}]", "");
str = Regex.Replace(str, match.Value, aux);
}
return new string(str);
}
return null;
}
Then the results for some sample inputs are:
Input:
Some text
_Expression{x}
_Expression{1}
_Expression{4}
_Expression{4.5} _Expression{4+4}
_Expression{4-4} _Expression{4*x}
_Expression{x/x}
_Expression{x^4}
_Expression{sin(x)}
Output:
Some text
x
1{1}
1{4}
1{4.5} 1{4+4}
1{4-4} 1{4*x}
1{x/x}
1{x^4}
1{sin(x)}
or
Input:
Some text
_Expression{x}
_Expression{4}
_Expression{4.5} _Expression{4+4}
_Expression{4-4} _Expression{4*x}
_Expression{x/x}
_Expression{x^4}
_Expression{sin(x)}
Output:
Some text
x
_Expression{4}
4.5 _Expression{4+4}
4-4 _Expression{4*x}
x/x
_Expression{x^4}
_Expression{sin(x)}
It feels very confusing to me this behaviour. I can't see why "(.+?)" does not work with some of them and it does with others... Or maybe I haven't defined something properly or my Replace is wrong? I can't see it...
Thanks a lot for the time! :)
There are some missing parts in your regular expression, for example it doesn't have the curly braces { and } escaped, since curly braces have a special meaning in a regular expression; they are used as quantifiers.
Use the one below.
For extracting the math expression between the curly braces, it uses a named capturing group with name mathExpression.
_Expression\{(?<mathExpression>.+?)\}
_Expression\{ : start with the fixed text_Expression{
(?<mathExpression> : start a named capturing group with name mathExpression
.+? : take the next characters in a non greedy way
) : end the named capturing group
\} : end with the fixed character }
The below example will output 2 matches
Regex regex = new(#"_Expression\{(?<mathExpression>.+?)\}");
var matches = regex.Matches(#"_Expression{4.5} _Expression{4+4}");
foreach (Match match in matches.Where(o => o.Success))
{
var mathExpression = match.Groups["mathExpression"];
Console.WriteLine(mathExpression);
}
Output
4.5
4+4
Truth is, I'm having a hard time writing a regex string to parse something in the form of
[[[tab name=dog content=cat|tab name=dog2 content=cat2]]]
This regex would be parsed so that I can dynamically build tabs as demonstrated here. Initially I tried a regex pattern like \[\[\[tab name=(?'name'.*?) content=(?'content'.*?)\]\]\]
But I realized I couldn't get the tab as a whole and build upon a query without doing a regex.replace. Is it possible to take the entire tab leading up to the pipe symbol as a group and then parse that group down from the sub key/value pairs?
This is the current regex string I'm working with \[\[\[(?'tab'tab name=(?'name'.*?) content=(?'content'.*?))\]\]\]
And here is my code for performing the regex. Any guidance would be appreciated.
public override string BeforeParse(string markupText)
{
if (CompiledRegex.IsMatch(markupText))
{
// Replaces the [[[code lang=sql|xxx]]]
// with the HTML tags (surrounded with {{{roadkillinternal}}.
// As the code is HTML encoded, it doesn't get butchered by the HTML cleaner.
MatchCollection matches = CompiledRegex.Matches(markupText);
foreach (Match match in matches)
{
string tabname = match.Groups["name"].Value;
string tabcontent = HttpUtility.HtmlEncode(match.Groups["content"].Value);
markupText = markupText.Replace(match.Groups["content"].Value, tabcontent);
markupText = Regex.Replace(markupText, RegexString, ReplacementPattern, CompiledRegex.Options);
}
}
return markupText;
}
Is this what you want?
string input = "[[[tab name=dog content=cat|tab name=dog2 content=cat2]]]";
Regex r = new Regex(#"tab name=([a-z0-9]+) content=([a-z0-9]+)(\||])");
foreach (Match m in r.Matches(input))
{
Console.WriteLine("{0} : {1}", m.Groups[1].Value, m.Groups[2].Value);
}
http://regexr.com/3boot
Maybe string.split will be better in that case? For example something like that :
strgin str = "[[[tab name=dog content=cat|tab name=dog2 content=cat2]]]";
foreach(var entry in str.Split('|')){
var eqBlocks = entry.Split('=');
var tabName = eqBlocks[1].TrimEnd(" content");
var content = eqBlocks[2];
}
Ugly code, but should work.
Try this:
Starts with a word boundary and followed only by allowed characters.
/\b[\w =]*/g
https://regex101.com/r/cI7jS7/1
Just distill the regex pattern down to the individual tab patterns such as name=??? content=??? and match that only. That pattern which will make each Match (two in you example) where the data can be extracted.
string text = #"[[[tab name=dog content=cat|tab name=dog2 content=cat2]]]";
string pattern = #"name=(?<Name>[^\s]+)\scontent=(?<Content>[^\s|\]]+)";
var result = Regex.Matches(text, pattern)
.OfType<Match>()
.Select(mt => new
{
Name = mt.Groups["Name"].Value,
Content = mt.Groups["Content"].Value,
});
The result is an enumerable list with the created dynamic entities with the tabs needed which can be directly bound to the control:
Note in the set notation [^\s|\]] the pipe | is treated as a literal in the set and not used as an or. The bracket ] does have to be escaped though to be treated as a literal. Finally the logic the parse will look for: "To not (^) be a space or a pipe or a brace for that set".
I want to do a Regex Match in c# to check whether a string starts with part of pattern.
Say if the pattern is "ABC...GHI" then valid strings can be in the format "A","AB","ABCDEF","ABCXYXGHI"
This is a sample code. What exactly regex has to be in the pattern to make it work
string pattern = "ABC...GHI"
code = "A" //valid
code = "ABC" valid
code = "ABCDE" //valid
code = "ABCXXX" //valid
code = "ABCXXXGHI" //valid
code = "ABCXXXGHIAA" //invalid
code = "B" //invalid
Regex.IsMatch(code, pattern)
You can use ? and make optional part of regexp. The final regexp string could be
A(B(C(.(.(.(G(H(I?)?)?)?)?)?)?)?)?
The final string is quite messy but you can create it automatically
The visualization of above regexp is here http://www.regexper.com/#A(B(C(.(.(.(G(H(I%3F)%3F)%3F)%3F)%3F)%3F)%3F)%3F)%3F
Are you looking for something like this?
var pat = new Regex(#"^A(B(C(.(Z)?)?)?)?");
var testStrings = new string[]
{
"ALPHA",
"ABGOOF",
"ABCblah",
"ABCbZ",
"FOOBAR"
};
foreach (var s in testStrings)
{
var m = pat.Match(s);
if (m.Success)
{
Console.WriteLine("{0} matches {1}", s, m.Value);
}
else
{
Console.WriteLine("No match found for {0}", s);
}
}
Results from that are:
ALPHA matches A
ABGOOF matches AB
ABCblah matches ABCb
ABCbZ matches ABCbZ
No match found for FOOBAR
The key is that everything after the A is optional. So if you wanted strings that start with A or AB, you'd have:
AB?
If you wanted to add ABC, you need:
A(BC?)?
Another character:
A(B(CZ?)?)?
Messy, but you could write code to generate the expression automatically if you had to.
Additional info
It's possible that you want the strings to be no longer than the pattern, and all characters must match the pattern. That is, given the pattern I showed above, "ABCxZ" would be valid, but "ABCblah" would not be valid because the "lab" part doesn't match the pattern. If that's the case, then you need to add a "$" to the end of the pattern to say that the string ends there. So:
var pat = new Regex(#"^A(B(C(.(Z)?)?)?)?$");
Or, in your example case:
"^A(B(C(.(.(.(G(H(I)?)?)?)?)?)?)?)?$"
I have a string.An example is given below.
[playlist]\r\npath1=url1\r\npath2=url2\r\npath=url3\r\npath4=url4\r\ncount=1
How can I extract path properties values from the above string.There may be many properties other than path properties.
Thr result i am expecting is
url1
url2
url3
url4
I think regular expression is best to do this. Any ideas(regular expressions) regarding the Rgular expression needed. How about using string.split method.. Which one is efficient? ..
Thanks in advance
Well, this regex works in your particular example:
path\d?=(.+?)\\r\\n
What isn't immediately obvious is if \r\n in your strings are literally the characters \r\n, or a carriage return + new line. The regex above matches those characters literally. If your text is actually this:
[playlist]
path1=url1
path2=url2
path=url3
path4=url4
count=1
Then this regex will work:
path\d?=(.+?)\n
And a quick example of how to use that in C#:
var str = #"[playlist]\r\npath1=url1\r\npath2=url2\r\npath=url3\r\npath4=url4\r\ncount=1";
var matches = Regex.Matches(str, #"path\d?=(.+?)\\r\\n");
foreach (Match match in matches)
{
var path = match.Groups[1].Value;
Console.WriteLine(path);
}
i have various strings that look like that:
$(gateway.jms.jndi.ic.url,0,tibjmsnaming, tcp)/topic/$(gateway.destination.prefix)$(gateway.StatusTopicName),$(gateway.jms.jndi.ic.username),$(gateway.jms.jndi.ic.password),abinding,tBinding
i'm trying to figure out a way to extract the $(...) sections and replace them with some other string.
is there anyway in C# to parse those groups and replace one by one with another string?
Thanks
This regular expression will capture those sections:
\$\([^)]+\)
Then replace like this (this example changes each match to it's uppercase equivalent - you can add whatever custom logic you wish):
Regex.Replace(candidate, #"\$\([^)]+\)", delegate(Match m) {
return m.ToString().ToUpper();
});
I am not so good with delegate.s Here is what i came up with using Andrew's regex:
string test1 = #"$(gateway.jms.jndi.ic.url,0,tibjmsnaming, tcp)/topic/$(gateway.destination.prefix)$(gateway.StatusTopicName),$(gateway.jms.jndi.ic.username),$(gateway.jms.jndi.ic.password),abinding,tBinding";
string regex1 = #"\$\([^)]+\)";
var matches = Regex.Matches(test1, regex1);
Console.WriteLine(matches.Count);
foreach (Match match in matches)
{
test1 = test1.Replace(match.Value, "your String");
}
Console.WriteLine(test1);