Preg-Match-All - 同义词文件

时间:2013-05-20 13:25:34

标签: php preg-match-all

我正在编写一个PHP脚本,它将解析一个文件(synonyms.dat),并用他们的父词协调一个同义词列表,大约150k字。

文件示例:

1|2
(adj)|one|i|ane|cardinal 
(noun)|one|I|ace|single|unity|digit|figure
1-dodecanol|1
(noun)|lauryl alcohol|alcohol
1-hitter|1
(noun)|one-hitter|baseball|baseball game|ball
10|2
(adj)|ten|x|cardinal 
(noun)|ten|X|tenner|decade|large integer
100|2
(adj)|hundred|a hundred|one hundred|c|cardinal 
(noun)|hundred|C|century|one C|centred|large integer
1000|2
(adj)|thousand|a thousand|one thousand|m|k|cardinal 
(noun)|thousand|one thousand|M|K|chiliad|G|grand|thou|yard|large integer
**10000|1
(noun)|ten thousand|myriad|large**

在上面的示例中,我想将一万个,无数个,大一个链接到1000个单词。

我尝试过各种方法,使用file_get_contents将.dat文件读入内存,然后在\ n中展开文件,并使用各种数组搜索技术查找“父”字及其同义词。但是,这非常慢,而且通常不会崩溃我的Web服务器。

我相信我需要做的是使用preg_match_all来爆炸字符串,然后迭代字符串,在适当的位置插入我的数据库。

$contents = file_get_contents($page);
preg_match_all("/([^\s]+)\|[0-9].*/",$contents,$out, PREG_SET_ORDER);

这匹配每个

1|2

1-dodecanol|1

1-hitter|1

但我不知道如何链接每个匹配之间的字段,IE是同义词本身。

此脚本旨在运行一次,以便将所有信息正确地提供到我的数据库中。对于那些感兴趣的人,我有一个数据库'synonym_index',它包含每个单词的唯一ID,以及单词。然后是另一个表'synonym_listing',它包含'word_id'列和'synomym_id'列,其中每列是synonym_index的外键。每个word_id可以有多个synonym_id。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

哇,对于这种类型的功能,您拥有包含表和索引的数据库。 PHP是为了提供请求/响应,而不是将大文件读入内存。我建议你把数据放在数据库中。这将更快 - 而且它是为它而制造的。

答案 1 :(得分:0)

您可以使用explode()将每一行拆分为字段。 (或者,根据输入的确切格式,fgetcsv()可能是更好的选择。)

说明性示例,几乎肯定需要针对您的特定用例和数据格式进行调整:

$infile = fopen('synonyms.dat', 'r');
while (!feof($infile)) {
    $line = rtrim(fgets($infile), "\r\n");
    if ( $line === '' ) {
        continue;
    }

    // Line follows the format HEAD_WORD|NUMBER_OF_SYNONYM_LINES
    list($headWord, $n) = explode('|', $line);
    $synonyms = array();

    // For each synonym line...
    while ( $n-- ) {
        $line = rtrim(fgets($infile), "\r\n");
        $fields = explode('|', $line);
        $partOfSpeech = substr(array_shift($fields), 1, -1);
        $synonyms[$partOfSpeech] = $fields;
    }

    // Now here, when $headWord is '**10000', $synonyms should be array(
    //     'noun' => array('ten thousand', 'myriad', 'large**')
    // )
}