【问题标题】:Regex (PHP) to extract a sentence that contains a link正则表达式(PHP)提取包含链接的句子
【发布时间】:2022-01-22 18:00:32
【问题描述】:

我想检索链接周围的整个句子,由标点符号(例如 . 或 ! 或 ? 或换行符)分隔。

目的是为链接提供更好的上下文。

例如,如果我有这个......

$input = "I don't want this piece! This is the <a href='https://example.com/my-sentence'>sentence</a> I want. In don't want this piece either";
$filter = "https://example.com/my-sentence";

...我需要解决这个问题...

$output = "This is the sentence I want.";

到目前为止,我设法隔离了一个不包含标签的句子,如下所示:

$input = "I don't want this piece. This is the sentence I want. In don't want this piece either";
$filter = "sentence";
$regex = '/[A-Z][^\\.;]*('.$filter.')[^\\.;]*/';
if (preg_match($regex, $input, $match))
$output = $match[0];

这很好用。接下来,我不知道如何绕过url中的标点符号。

我首先探索了隔离锚点并对其进行正则表达式,这适用于任何单个示例,但可能会在野外产生冲突(锚点复制其他锚点或随机文本)。

另一种方法似乎是 strip_tags,类似于...

$input = strip_tags($input);

...问题是我需要同时剥离而不是剥离它们。

也许一个更具体的正则表达式或函数的一些智能包装可以带来一个简单的方法,或者它可能是一个死胡同并且需要一些其他方法,我不知道,但现在我被卡住了,请帮忙!

【问题讨论】:

  • "delimited by punctuation" 可能注定会失败,只要你真正想要的句子会提到E. A. Milne或@ 987654326@ ...
  • 确实,我知道这一点,但我希望这种情况很少见。 (我可以指导作者如何放置链接,但如何应用严格的标记......不是真的)

标签: php regex


【解决方案1】:

尽管您不关心缩写,您可以匹配除?!. 以外的字符,或在特定过滤字符串前后任意零次或多次的类似链接的子字符串:

$input = "I don't want this piece! This is the <a href='https://example.com/my-sentence'>sentence</a> I want. In don't want this piece either";
$filter = "sentence";
$regex = '~\b(?:[^.?!]|https?://[^<>\s"\']++)*?'.preg_quote($filter, '~').'(?:[^.?!]|https?://[^<>\s"\']++)*~u';
if (preg_match_all($regex, $input, $match)){
  print_r( array_map(function($x) {return strip_tags($x);}, $match[0]) );
}

请参阅PHP demo。输出:

Array
(
    [0] => This is the sentence I want
)

请参阅regex demo详情

  • \b - 单词边界
  • (?:[^.?!]|https?://[^&lt;&gt;\s"\']++)*? - 除.?!http 之外的字符出现零次或多次(尽可能少),可选s://,然后是一个或多个&lt;&gt;、空格、"' 以外的字符
  • sentence - 过滤字符串
  • (?:[^.?!]|https?://[^&lt;&gt;\s"\']++)* - 除了.?!http 之外的字符,尽可能多地出现零次或多次,可选的s://,然后是一个或多个&lt;&gt;、空格、"' 以外的字符

【讨论】:

  • 太好了,非常感谢!请注意,我正在寻找的实际过滤器是 $filter = "https://example.com/my-sentence";,但是当我切换到它时它也能正常工作。
  • @LucianDavidescu 确保你 preg_quote 过滤器。
  • 所以我问的确切代码如下所示:3v4l.org/37Snq
  • 是的,这就是我建议的代码。使用什么作为过滤器取决于您。
  • @LucianDavidescu 是的,在模式末尾添加[.?!]*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-25
相关资源
最近更新 更多