Parse and replace string using Regex - c#

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

Related

Replacing a portion of a string with an exact matching

I just want to replace a portion of a string only if matches the given text.
My use case is as follows:
var text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
string result = text.Replace("wd:response", "response");
/*
* expecting the below text
<response><wd:response-data></wd:response-data></response>
*
*/
I followed the following answers:
Way to have String.Replace only hit "whole words"
Regular expression for exact match of a string
But I failed to achieve what I want.
Please share your thoughts/solutions.
Sample on
https://dotnetfiddle.net/pMkO8Q
In general, you should really be parsing and manipulating XML as XML, using functions that know how XML works and what's legal in the language. Regex and other naive text manipulation will often lead you into trouble.
That said, for a very simple solution to this specific problem, you can do this with two replaces:
var text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
text.Replace("wd:response>", "response>").Replace("wd:response ", "response ")
(Note the spaces at the end of the parameters to the second replace.)
Alternatively use a regex similar to "wd:response\s*>"
The easiest way to achieve your result as per your .net fiddle is use the replace as below.
string result = text.Replace("wd:response>", "response>");
But proper way to achieve this is parsing using XML
You can capture the string wd-response in a capturing group and replace using Regex.Replace using the MatchEvaluator like this.
Regex explanation - <[/]?(wd:response)[\s+]?>
Match < literally
Match / optionally hence the ?
Match the string wd:response and place it in a capturing group enclosed with ()
Match one or more optional whitespace [\s+]?
Match > literally
public class Program
{
public static void Main(string[] args)
{
string text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
string replacePattern = "response";
string pattern = #"<[/]?(wd:response)[\s+]?>";
string replacedPattern = Regex.Replace(text, pattern, match =>
{
// Extract the first group
Group group = match.Groups[1];
// Replace the group value with the replacePattern
return string.Format("{0}{1}{2}", match.Value.Substring(0, group.Index - match.Index), replacePattern, match.Value.Substring(group.Index - match.Index + group.Length));
});
Console.WriteLine(replacedPattern);
}
}
Outputting:
<response><wd:response-data></wd:response-data></response >

Regex within a regex?

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

c# regularexpression how to find two records in the string

ok i am building up my email templating engine and trying to break up some of the text between {{{ }}} from my this text
var matches = Regex.Matches("sdfsdfsdf{{{GetServices:Pilotage}}}sdfsdfsdf dfsdf{{{GetServices:Berth Fee}}}sdfdsf{{sss", "{{{(.*)}}}");
how can i parse this string so i get this as a result array. i have been trying different things but with no avail. how can i achieve this
1)GetServices:Pilotage
2)GetServices:Berth Fee
Your attempt (although maybe not optimal) should work if you force it to be non-greedy:
{{{(.*?)}}}
Just add a ? after the *.
Use Grouping to retrieve the matches.
var input = "sdfsdfsdf{{{GetServices:Pilotage}}}sdfsdfsdf dfsdf{{{GetServices:Berth Fee}}}sdfdsf{{sss\", \"{{{(.*)}}}";
var matches = Regex.Matches(input, "\\{\\{\\{(GetServices:[^{]*)\\}\\}\\}");
var result = new List<string>();
foreach (Match match in matches)
{
if (match.Groups.Count == 2)
{
result.Add(match.Groups[1].ToString());
}
}
You could try this regex:
(\{{3}\w*\:[\w\ ]*\}{3})+
Edit:
For obtaining the value, see answer:
Find each RegEx match in string
The pattern would be "\{{3}(.+?)\}{3}" or "\{{3}(.*?)\}{3}". It depends on your need if the string in between is optional or required.

string placeholder and regular expressions

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:.+?\}

Regex to check a string

I'm trying to check a string and then extract all the variables which starts with #. I can't find the appropriate regular expression to check the string. The string may start with # or " and if it's started with " it should have a matching pair ".
Example 1:
"ip : "+#value1+"."+#value2+"."+#value3+"."+#value4
Example 2:
#nameParameter "#yahoo.com"
Thanks
It would probably be easiest to first split the string on each quoted string, then check the unquoted parts for #'s. For example all quoted strings could be: /"[^"]*"/, calling Regex.Split on your string would return an array of strings of the non-quoted parts, which you could then use the expression /#\w+/ to find any #'s.
Try this:
string text = "#nameParameter \"#yahoo.com\"";
Regex variables = new Regex(#"(?<!"")#\w+", RegexOptions.Compiled);
foreach (Match match in variables.Matches(text))
{
Console.WriteLine(match.Value);
}
To check the strings you have provided in your post:
(^("[^"\r\n]"\s+#[\w.]+\s*+?)+)|(((^#[\w.]+)|("#[\w.]+"))\s*)+

Categories

Resources