我编写了一个正则表达式,可以自动检测用户输入的自由文本中的URL.这不是一开始就看起来那么简单的任务.杰夫阿特伍德在他的帖子中写道.
他的正则表达式有效,但在检测完成后需要额外的代码.
我已经设法写了一个正则表达式,一次完成所有事情.这就是它的样子(我把它分解成单独的行以使它更容易理解它的作用):
1 (?<outer>\()?
2 (?<scheme>http(?<secure>s)?://)?
3 (?<url>
4 (?(scheme)
5 (?:www\.)?
6 |
7 www\.
8 )
9 [a-z0-9]
10 (?(outer)
11 [-a-z0-9/+&@#/%?=~_()|!:,.;?šž??]+(?=\))
12 |
13 [-a-z0-9/+&@#/%?=~_()|!:,.;?šž??]+
14 )
15 )
16 (?<ending>(?(outer)\)))
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在使用命名捕获组(稍后使用Regex.Replace()),并且还包括一些本地字符(čšžćđ),这些字符也允许我们对本地化的URL进行解析.如果您愿意,可以轻松省略它们.
无论如何.这是它的作用(指行号):
if声明说:如果"sheme"存在,那么www.part是可选的,否则字符串必须是一个链接(所以这个正则表达式检测所有以http或www开头的字符串)http://或者www.应该是字母或数字(如果你想覆盖更多的链接,这可以扩展,但我决定不这样做,因为我想不出一个可以开头的链接一些不起眼的人物)if声明说:如果"外部"(大括号)存在,则捕获所有内容,直到最后关闭的大括号,否则捕获全部它们中的第一行和最后一行\s*也是如此,因此用户也可以在粘贴链接之前编写开括号并在其中放置一个空格.
无论如何.我将使用实际锚点HTML元素进行链接替换的代码看起来完全如下:
value = Regex.Replace(
value,
@"(?<outer>\()?(?<scheme>http(?<secure>s)?://)?(?<url>(?(scheme)(?:www\.)?|www\.)[a-z0-9](?(outer)[-a-z0-9/+&@#/%?=~_()|!:,.;?šž??]+(?=\))|[-a-z0-9/+&@#/%?=~_()|!:,.;?šž??]+))(?<ending>(?(outer)\)))",
"${outer}<a href=\"http${secure}://${url}\">http${secure}://${url}</a>${ending}",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在使用命名捕获组来替换与Anchor标记的链接:
"${outer}<a href=\"http${secure}://${url}\">http${secure}://${url}</a>${ending}"
Run Code Online (Sandbox Code Playgroud)
我也可以在锚点显示中省略http(s)部分,以使链接看起来更友好,但是现在我决定不这样做.
我希望我的链接也可以替换为缩短.因此,当用户复制一个非常长的链接时(例如,如果他们从谷歌地图复制链接,通常生成长链接)我想缩短锚标记的可见部分.链接可以工作,但锚标记的可见部分将缩短为一些字符.我还可以尽可能地在最后添加省略号(并使事情更加完美).
Regex.Replace()方法是否支持替换符号,以便我仍然可以使用单个调用?string.Format()当您想要以字符串格式(小数,日期等)格式化值时,与方法类似的东西.
您可以分成${url}两个捕获组 - urlhead,其中包含要显示的字符数,以及urltail其余的字符数。这是一个包含 10 个字符的示例;这在某种程度上简化了删除条件,最后一个(?<ending>(?(outer)(?=\\))))应该处理这个问题 - 它会)在需要时回溯并捕获最后一个:
(?<outer>(?<=\\())?\n(?<scheme>http(?<secure>s)?://)?\n(?<url>\n (?(scheme)\n (?:www\\.)?\n |\n www\\.\n )\n [a-z0-9]\n [-a-z0-9/+&@#/%?=~_()|!:,.;\xc4\x8d\xc5\xa1\xc5\xbe\xc4\x87\xc4\x91]{1,10}\n)\n(?<urltail>[-a-z0-9/+&@#/%?=~_()|!:,.;\xc4\x8d\xc5\xa1\xc5\xbe\xc4\x87\xc4\x91]+)\n(?<ending>(?(outer)(?=\\))))\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,我还进行了更改outer并ending进行了环视,因此它们不会被捕获和替换。本例中的替换字符串如下所示:
<a href=\\"http${secure}://${url}${urltail}\\">http${secure}://${url}</a>\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1128 次 |
| 最近记录: |