【问题标题】:Does anyone have a PHP snippet of code for grabbing the first "sentence" in a string?有没有人有一个 PHP 代码片段来获取字符串中的第一个“句子”?
【发布时间】:2010-11-11 06:01:30
【问题描述】:

如果我有这样的描述:

“我们更喜欢可以回答的问题,而不仅仅是讨论。提供详细信息。写得清楚简单。”

我想要的只是:

“我们更喜欢可以回答的问题,而不仅仅是讨论。”

我想我会搜索一个正则表达式,比如“[.!\?]”,确定 strpos,然后从主字符串中做一个 substr,但我想这是很常见的事情,所以希望有人有一个sn-p躺在身边。

【问题讨论】:

  • 这是一个真正的难题。如果您需要可靠的结果,我建议您查看 NLP 包。分词器可以识别句子结尾字符(“?”、“.”、“;”等,具体取决于您的预期用途),您可以对其进行拆分。

标签: php string code-snippets


【解决方案1】:

一种稍微昂贵的表达方式,但如果您希望选择多种类型的标点符号作为句子终止符,它的适应性会更好。

$sentence = preg_replace('/([^?!.]*.).*/', '\\1', $string);

查找后跟空格的终止字符

$sentence = preg_replace('/(.*?[?!.](?=\s|$)).*/', '\\1', $string);

【讨论】:

  • 谢谢。我想我可以接受成本,因为它会被缓存。
  • 其实,刚刚意识到,这少了一件。因为它将所有内容都抓取到最后,所以它会丢弃实际的标点符号。一种 ”。”在括号内的搜索表达式的末尾似乎解决了。 preg_replace('/([^?!.]*.).*/', '\\1', $str);
  • 你一定是在我修改之前抓住了代码:) 如果你再看一遍,那就是我发布的内容。
  • 是的,我在发表评论后就看到了。下面有人指出它应该是句点(或其他句子终止符),后跟至少一个空格(例如允许域名)。我试了一下,但无法找到正确的表达方式,并且添加“\s”不起作用。
  • 如果句点后跟新行而不是空格,则此正则表达式将失败。您可能想先通过preg_replace( '/\s+/', ' ', $text); 运行它。
【解决方案2】:
<?php
$text = "We prefer questions that can be answered, not just discussed. Provide details. Write clearly and simply.";
$array = explode('.',$text);
$text = $array[0];
?>

【讨论】:

  • 对此回复+1。应该注意的是,这将在所有 . (即句点字符)上爆炸。因此,如果句子包含诸如“即”之类的缩写词或“例如”你会遇到问题。除此之外,这是最简单的选择。
  • 然而,并不是所有的句子都以“.”结尾。我需要一些可以处理“!”的东西和 ”?”我也很确定,所以我认为它必须使用正则表达式。
  • 你可以通过'!'、'?'等进一步分割$array的元素
  • 但是你不能动态选择分割的依据。
【解决方案3】:

我之前的正则表达式似乎在测试器中有效,但在实际 PHP 中无效。我已编辑此答案以提供完整的、可工作的 PHP 代码和改进的正则表达式。

$string = 'A simple test!';
var_dump(get_first_sentence($string));

$string = 'A simple test without a character to end the sentence';
var_dump(get_first_sentence($string));

$string = '... But what about me?';
var_dump(get_first_sentence($string));

$string = 'We at StackOverflow.com prefer prices below US$ 7.50. Really, we do.';
var_dump(get_first_sentence($string));

$string = 'This will probably break after this pause .... or won\'t it?';
var_dump(get_first_sentence($string));

function get_first_sentence($string) {
    $array = preg_split('/(^.*\w+.*[\.\?!][\s])/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
    // You might want to count() but I chose not to, just add   
    return trim($array[0] . $array[1]);
}

【讨论】:

  • 这似乎不起作用。自从您第一次发布以来,您是否更改了它?
  • 所以这不仅现在有效,而且最终,它实际上解决了我的现实问题,而 Ian 没有......(虽然一开始它确实如此)。正如我在上面评论的那样,也许这是因为结果是 Unicode 字符串……不确定,但值得深思。感谢您的功能-我会定义的。一次又一次地使用它。
【解决方案4】:

试试这个:

$content = "My name is Younas. I live on the pakistan. My email is **fromyounas@gmail.com** and skype name is "**fromyounas**". I loved to work in **IOS development** and website development . ";

$dot = ".";

//find first dot position     

$position = stripos ($content, $dot); 

//if there's a dot in our soruce text do

if($position) { 

    //prepare offset

    $offset = $position + 1; 

    //find second dot using offset

    $position2 = stripos ($content, $dot, $offset); 

    $result = substr($content, 0, $position2);

   //add a dot

   echo $result . '.'; 

}

输出是:

我的名字是尤纳斯。我住在巴基斯坦。

【讨论】:

    【解决方案5】:
    current(explode(".",$input));
    

    【讨论】:

      【解决方案6】:

      我可能会在 PHP 中使用众多子字符串/字符串拆分函数中的任何一个(这里已经提到了一些)。 但也要寻找“.”或“.\n”(可能还有“.\n\r”),而不仅仅是“.”。以防万一,无论出于何种原因,该句子都包含一个不带空格的句点。我认为这会增加您获得真正结果的可能性。

      例如,只搜索“.”上:

      "I like stackoverflow.com."
      

      会得到你:

      "I like stackoverflow."
      

      如果真的,我相信你会更喜欢:

      "I like stackoverflow.com."
      

      一旦您进行了基本搜索,您可能会遇到一两次可能会遗漏某些内容的情况。边跑边调!

      【讨论】:

      • 大多数字符串中可能没有换行符。
      • 我确实认为许多字符串(以及我的项目中的一些字符串)都会有 URL ......所以最好找出解决方案,尽管上面接受的答案现在很好.
      【解决方案7】:

      试试这个:

      reset(explode('.', $s, 2));
      

      【讨论】:

        猜你喜欢
        • 2015-03-07
        • 1970-01-01
        • 1970-01-01
        • 2021-11-04
        • 1970-01-01
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 2020-04-28
        相关资源
        最近更新 更多