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) ""
}
}