3

你好!

我想从文本中提取所有引用。此外,应提取被引人的姓名。DayLife 在这方面做得很好。

例子:

“他们认为‘游戏结束’,”一位高级政府官员说。

他们认为“游戏结束”这句话应该被引用一位高级政府官员。

你认为这可能吗?如果您检查是否提到了被引用的人,您只能区分引用和引号中的单词。

例子:

“我认为这很严重,而且正在恶化,”马伦上将周日在 CNN 的“国情咨文”节目中说。

国情咨文段落不是引文。但是您如何检测到这一点?a)您检查是否提到了被引用的人。b)您计算假定引用中的空格。如果空格少于 3 个,则不会是引号,对吗?我更喜欢 b) 因为并不总是有一个被引用的人。

如何开始?

我将首先用一种类型替换所有类型的引号,以便您稍后只需要检查一个引号。

<?php
$text = '';
$quote_marks = array('“', '”', '„', '»', '«');
$text = str_replace($quote_marks, '"', $text);
?>

然后我会提取引号之间包含超过 3 个空格的所有短语:

<?php
function extract_quotations($text) {
   $result = preg_match_all('/"([^"]+)"/', $text, $found_quotations);
   if ($result == TRUE) {
      return $found_quotations;
      // check for count of blank spaces
   }
   return array();
}
?>

你怎么能改善这个?

我希望你能帮助我。非常感谢您!

4

3 回答 3

3

正如 ceejayoz 已经指出的那样,这不适合单个函数。您在问题中描述的内容(检测句子的引号转义部分的语法功能 - 即“我认为它很严重并且它正在恶化”与“国情咨文”)最好用图书馆来解决可以将自然语言分解为标记。我不知道 PHP 中有任何此类库,但您可以查看您将在 python 中使用的项目大小:http ://www.nltk.org/

我认为您能做的最好的事情就是定义一组您手动验证的语法规则。像这样的东西怎么样:

abstract class QuotationExtractor {

    protected static $instances;

    public static function getAllPossibleQuotations($string) {
        $possibleQuotations = array();
        foreach (self::$instances as $instance) {
            $possibleQuotations = array_merge(
                $possibleQuotations,
                $instance->extractQuotations($string)
            );
        }
        return $possibleQuotations;
    }

    public function __construct() {
        self::$instances[] = $this;
    }

    public abstract function extractQuotations($string);

}

class RegexExtractor extends QuotationExtractor {

    protected $rules;

    public function extractQuotations($string) {
        $quotes = array();
        foreach ($this->rules as $rule) {
            preg_match_all($rule[0], $string, $matches, PREG_SET_ORDER);
            foreach ($matches as $match) {
                $quotes[] = array(
                    'quote' => trim($match[$rule[1]]),
                    'cited' => trim($match[$rule[2]])
                );
            }
        }
        return $quotes;
    }

    public function addRule($regex, $quoteIndex, $authorIndex) {
        $this->rules[] = array($regex, $quoteIndex, $authorIndex);
    }

}

$regexExtractor = new RegexExtractor();
$regexExtractor->addRule('/"(.*?)[,.]?\h*"\h*said\h*(.*?)\./', 1, 2);
$regexExtractor->addRule('/"(.*?)\h*"(.*)said/', 1, 2);
$regexExtractor->addRule('/\.\h*(.*)(once)?\h*said[\-]*"(.*?)"/', 3, 1);

class AnotherExtractor extends Quot...

如果你有类似上面的结构,你可以通过任何/所有运行相同的文本,并列出可能的引用以选择正确的引用。我已经用这个线程运行代码作为测试的输入,结果是:

array(4) {
  [0]=>
  array(2) {
    ["quote"]=>
    string(15) "Not necessarily"
    ["cited"]=>
    string(8) "ceejayoz"
  }
  [1]=>
  array(2) {
    ["quote"]=>
    string(28) "They think it's `game over,'"
    ["cited"]=>
    string(34) "one senior administration official"
  }
  [2]=>
  array(2) {
    ["quote"]=>
    string(46) "I think it is serious and it is deteriorating,"
    ["cited"]=>
    string(14) "Admiral Mullen"
  }
  [3]=>
  array(2) {
    ["quote"]=>
    string(16) "Not necessarily,"
    ["cited"]=>
    string(0) ""
  }
}
于 2009-08-27T10:08:14.047 回答
3

如果空格少于 3 个,则不会是引号,对吗?

“不一定,”ceejayoz 说。

国情咨文段落不是引文。但是您如何检测到这一点?a)您检查是否提到了被引用的人。b)您计算假定引用中的空格。如果空格少于 3 个,则不会是引号,对吗?我更喜欢 b) 因为并不总是有一个被引用的人。

b) 甚至不适用于这个例子——“国情咨文”中有 3 个空格。

于 2009-08-24T17:01:24.057 回答
0

引文总是有标点符号——要么是结尾的逗号,表示后面是说话者的名字或标题,要么是句子的结尾(.!?)。

于 2009-08-24T17:17:00.297 回答