【发布时间】:2016-02-01 06:38:03
【问题描述】:
我有以下正则表达式(粗略匹配看起来像 URLS 的东西)
(https?://\S*)
但是,这是在句子中提取 URL,因此尾随点可能是句子的结尾,而不是 URL 的合法部分。
让捕获组忽略尾随句号、逗号、冒号、分号等的魔法咒语是什么?
(我知道匹配 URL 是一场噩梦,这只需要支持松散匹配,因此非常简单的正则表达式)
这是我的测试字符串:
lorem http://www.example.com lorem https://example.com lorem
http://www.example.com.
lorem https://example.com.
这应该匹配所有 example.com 实例。
(我正在使用 Expresso 和 .NET 对其进行测试)
带有尾随点和新行的测试结果:
Expected string length 62 but was 64. Strings differ at index 31.
Expected: "<a href="http://www.example.com">http://www.example.com</a>.\n\r"
But was: "<a href="http://www.example.com.\n">http://www.example.com.\n</a>\r"
------------------------------------------^
示例代码
public class HyperlinkParser
{
private readonly Regex _regex =
new Regex(
@"(https?://\S*[^\.])");
public string Parse(string original)
{
var parsed = _regex.Replace(original, "<a href=\"$1\">$1</a>");
return parsed;
}
}
示例测试
[TestFixture]
public class HyperlinkParserTests
{
private readonly HyperlinkParser _parser = new HyperlinkParser();
private const string NO_HYPERLINKS = "dummy-text";
private const string FULL_URL = "http://www.example.com";
private const string FULL_URL_PARSED = "<a href=\"" + FULL_URL + "\">" + FULL_URL + "</a>";
private const string FULL_URL_TRAILING_DOT = FULL_URL + ".";
private const string FULL_URL_TRAILING_DOT_PARSED = "<a href=\"" + FULL_URL + "\">" + FULL_URL + "</a>.";
private const string TRAILING_DOT_AND_NEW_LINE = FULL_URL_TRAILING_DOT + "\n\r";
private const string TRAILING_DOT_AND_NEW_LINE_PARSED = FULL_URL_TRAILING_DOT_PARSED + "\n\r";
private const string COMPLEX_TEXT = "Leading stuff http://www.example.com. Other stuff.";
private const string COMPLEX_TEXT_PARSED = "Leading stuff <a href=\"http://www.example.com\">http://www.example.com</a>. Other stuff.";
[TestCase(NO_HYPERLINKS, NO_HYPERLINKS)]
[TestCase(FULL_URL, FULL_URL_PARSED)]
[TestCase(FULL_URL_TRAILING_DOT, FULL_URL_TRAILING_DOT_PARSED)]
[TestCase(TRAILING_DOT_AND_NEW_LINE, TRAILING_DOT_AND_NEW_LINE_PARSED)]
[TestCase(COMPLEX_TEXT, COMPLEX_TEXT_PARSED)]
public void Parsing(string original, string expected)
{
var actual = _parser.Parse(original);
Assert.That(actual, Is.EqualTo(expected));
}
}
【问题讨论】:
-
能否提供一个测试代码?拨弄一下IDEONE.com 会很有帮助。用空格测试字符串不是一件容易的事,我们可能会在与您不同的字符串上进行测试。
-
@WiktorStribiżew 我已经添加了代码,我无法在在线小提琴上进行解析。通过在
[^\.]的位置中使用[^\W],我已经成功地完成了这项工作。