I have a problem, for example I have a text:
input = "text, *text*, text, text, (text), [text], [some_text with _*](http://.....) *text*, text, text, (text), [text]"
I'm trying to replace characters '_', '*', '[', ']', '(', ')' to '\_', '\*' etc.
I'm writing:
pattern = @"(?<!\[(?<text>.*)\]\((?<url>.*))([[\]\(\)*_])";
input = Regex.Replace(input, pattern, @"\$1");
System output: "text, \*text\*, text, text, \(text\), \[text\], \[some\_text with \_ \* \]\(http://.....) \*text\*, text, text, \(text\), \[text\]"
How to make sure that the design of the link []() doesn't change? i.e. it would look like:
desired output:"text, \*text\*, text, text, \(text\), \[text\], [some\_text with \_ \*](http://.....) \*text\*, text, text, \(text\), \[text\]"
CodePudding user response:
You need to match and capture the markdown link part, and just match the chars you need to escape, and then use a match evaluator in the replacement part:
var input = "text, *text*, text, text, (text), [text], [some_text with _*](http://.....) *text*, text, text, (text), [text]";
var pattern = @"(\[[^][]*]\([^()]*\))|[][()*_]";
Console.WriteLine(Regex.Replace(input, pattern, m =>
m.Groups[1].Success ? m.Groups[1].Value : $@"\{m.Value}"));
See the C# demo. Details:
(\[[^][]*]\([^()]*\))
- Capturing group 1 matching[
, then zero or more chars other than[
and]
(with[^][]*
), then a]
char,(
, then zero or more chars other than(
and)
(with[^()]*
) and then a)
char|
- or[][()*_]
- a character class that matches:]
(note it is not escaped because it is the first char in the character class),[
,(
,)
,*
or_
chars.
The m => m.Groups[1].Success ? m.Groups[1].Value : $@"\{m.Value}"
replacement replaces the match found with Group 1 value if Group 1 matched, else, the replacement is the match value (the special char defined in the character class) with a \
prepended.