使用 Regex 解析 URL,忽略 Markdown 中的代码块和代码片段
Parse URLs using Regex, Ignoring Code Blocks and Code Snippets in Markdown
我目前在我的 C#/.NET Core 应用程序中使用这个正则表达式来解析 HTTP、HTTPS 和 FTP 来自降价文件的 url:
static readonly Regex _urlRegex = new Regex(@"(((http|ftp|https):\/\/)+[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?)");
void UpdateGitHubReadme(string gitHubRepositoryName, string gitHubReadmeText)
{
var updatedMarkdown = _urlRegex.Replace(gitHubReadmeText, x => HandleRegex(x.Groups[0].Value, gitHubRepositoryName.Replace(".", "").Replace("-", "").ToLower(), "github", gitHubUser.Alias));
//handle updated markdown
}
static string HandleRegex(in string url, in string repositoryName, in string channel, in string alias)
{
//handle url
}
我希望更新此正则表达式以忽略降价代码块和降价代码片段中的 URLs。
示例 1
应忽略以下 URL,因为它在代码块内:
```
{
"name": "布兰登",
“博客”:“https://codetraveler.io”
}
```
示例 2
应忽略以下 URL,因为它在代码段内:
`curl -I https://www.keycdn.com`
您可以利用已有匹配求值器的现有代码作为 Regex.Replace
中的替换参数。
您需要向当前正则表达式添加一个替代项(使用 |
替代运算符)以匹配您要忽略匹配项的上下文,然后检查哪个组匹配。
您应该添加的备选方案是 (?<!`)(`(?:`{2})?)(?:(?!).)*?
,它匹配
(?<!`)
- 不允许立即向左反引号
(`(?:`{2})?)
- 第 1 组:一个反引号,然后是一个可选的双反引号序列
(?:(?!).)*?
- 除换行符以外的任何字符,零次或多次出现但尽可能少,不会启动与第 1 组 中捕获的相同字符序列
</code> - 在组 1</li> 中捕获的相同字符序列
</ul>
<p>查看示例代码:</p>
<pre><code>static readonly Regex _urlRegex = new Regex(@"(?<!`)(`(?:`{2})?)(?:(?!).)*?|((?:ht|f)tps?://[\w-]+(?>\.[\w-]+)+(?:[\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)", RegexOptions.Singleline);
void UpdateGitHubReadme(string gitHubRepositoryName, string gitHubReadmeText)
{
var updatedMarkdown = _urlRegex.Replace(gitHubReadmeText, x => x.Groups[2].Success ?
HandleRegex(x.Groups[0].Value, gitHubRepositoryName.Replace(".", "").Replace("-", "").ToLower(), "github", gitHubUser.Alias) : x.Value);
//handle updated markdown
}
我稍微修改了 URL 模式,使其更简洁、更高效。
我目前在我的 C#/.NET Core 应用程序中使用这个正则表达式来解析 HTTP、HTTPS 和 FTP 来自降价文件的 url:
static readonly Regex _urlRegex = new Regex(@"(((http|ftp|https):\/\/)+[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?)");
void UpdateGitHubReadme(string gitHubRepositoryName, string gitHubReadmeText)
{
var updatedMarkdown = _urlRegex.Replace(gitHubReadmeText, x => HandleRegex(x.Groups[0].Value, gitHubRepositoryName.Replace(".", "").Replace("-", "").ToLower(), "github", gitHubUser.Alias));
//handle updated markdown
}
static string HandleRegex(in string url, in string repositoryName, in string channel, in string alias)
{
//handle url
}
我希望更新此正则表达式以忽略降价代码块和降价代码片段中的 URLs。
示例 1
应忽略以下 URL,因为它在代码块内:
```
{
"name": "布兰登",
“博客”:“https://codetraveler.io”
}
```
示例 2
应忽略以下 URL,因为它在代码段内:
`curl -I https://www.keycdn.com`
您可以利用已有匹配求值器的现有代码作为 Regex.Replace
中的替换参数。
您需要向当前正则表达式添加一个替代项(使用 |
替代运算符)以匹配您要忽略匹配项的上下文,然后检查哪个组匹配。
您应该添加的备选方案是 (?<!`)(`(?:`{2})?)(?:(?!).)*?
,它匹配
(?<!`)
- 不允许立即向左反引号(`(?:`{2})?)
- 第 1 组:一个反引号,然后是一个可选的双反引号序列(?:(?!).)*?
- 除换行符以外的任何字符,零次或多次出现但尽可能少,不会启动与第 1 组 中捕获的相同字符序列
</code> - 在组 1</li> 中捕获的相同字符序列 </ul> <p>查看示例代码:</p> <pre><code>static readonly Regex _urlRegex = new Regex(@"(?<!`)(`(?:`{2})?)(?:(?!).)*?|((?:ht|f)tps?://[\w-]+(?>\.[\w-]+)+(?:[\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)", RegexOptions.Singleline); void UpdateGitHubReadme(string gitHubRepositoryName, string gitHubReadmeText) { var updatedMarkdown = _urlRegex.Replace(gitHubReadmeText, x => x.Groups[2].Success ? HandleRegex(x.Groups[0].Value, gitHubRepositoryName.Replace(".", "").Replace("-", "").ToLower(), "github", gitHubUser.Alias) : x.Value); //handle updated markdown }
我稍微修改了 URL 模式,使其更简洁、更高效。