【问题标题】:How to turn opening/closing tags into an associative array in PHP?如何在 PHP 中将打开/关闭标签转换为关联数组?
【发布时间】:2019-09-20 19:40:44
【问题描述】:

我有一个自然语言处理分析树

(S
  (NP I)
  (VP
    (VP (V shot) (NP (Det an) (N elephant)))
    (PP (P in) (NP (Det my) (N pajamas)))))

我想将它存储在一个关联数组中,但是 PHP 中没有函数,因为 NLP 通常是在 python 中完成的。

因此,我应该解析左括号和右括号以构建树结构的关联数组。我能想到两个选择

  1. 用任意 XML 或 HTML 标记替换括号,并将其解析为 XML 或 HTML 文档。
  2. 使用正则表达式。

我认为第一种方法是非标准的,正则表达式模式在复杂情况下可能会中断。

您能提出一个可靠的方法吗?

关联数组可以有任何形式,因为它不难操作(我需要在循环中使用它),但它可以是类似的东西

Array (
[0] = > word => ROOT, tag => S, children => Array (
    [0] word => I, tag = > NP, children => Array()
    [1] word => ROOT, tag => VP, children => Array (
        [0] => word => ROOT, tag => VP, children => Array ( .... )
        [1] => word => ROOT, tag => PP, children => Array ( .... )
)
)
)

也可以

Array (
[0] = > Array([0] => S, [1] => Array (
    [0] Array([0] => NP, [1] => 'I') // child array is replaced by a string
    [1] Array([0] => VP, [1] => Array (
        [0] => Array([0] => VP, [1] => Array ( .... )
        [1] => Array([0] => PP, [1] => Array ( .... )
    )
)

【问题讨论】:

  • 您能否提供预期结果的print_r()var_dump()?如果您需要不同的语言来使用彼此的数据,您应该考虑使用普遍接受的序列化方法,例如 JSON。
  • @MonkeyZeus 抱歉,我应该提供它。我添加了一个例子。我从 Standford CoreNLP 获得它,它是用 Java 编写的。虽然它给出了 XML 和 JSON 格式的结果,但解析部分的提供与上面完全相同,可能是因为括号是语言研究中的标准标记。
  • @Emma 不,这是 python 的包装器,用于从 CoreNLP 获取解析结果。它返回上面给出的字符串。如果我找到一个 python 函数,我可以将它复制为一个 PHP 函数,但即使在 python 中,人们也有兴趣绘制解析(如上图)而不是排列在一个数组中。
  • @mickmackusa 我在您的评论之后添加了一个简化的预期输出数组。
  • 不,您仍在使用( .... )。在尝试自我解决的情况下,我可以投票。否则,这是一个“需求转储”——有些人认为值得一票。在提供编码尝试之前,我不会考虑回答。这符合我的发帖理念,即保护这个社区不被滥用为免费的编码服务。

标签: php regex recursion xml-parsing preg-match


【解决方案1】:

使用 bisonflex 之类的词法分析器生成器,或者只是手动编写自己的词法分析器,这个 answer 有一些您需要的有用信息。

这是一个用 PHP 编写的快速而肮脏的 POC sn-ps,它将按预期输出一个关联数组。

$data =<<<EOL
(S
  (NP I)
  (VP
    (VP (V shot) (NP (Det an) (N elephant)))
    (PP (P in) (NP (Det my) (N pajamas)))))
EOL;

$lexer = new Lexer($data);
$array = buildTree($lexer, 0);
print_r($array);

function buildTree($lexer, $level)
{
    $subtrees = [];
    $markers = [];
    while (($token = $lexer->nextToken()) !== false) {
        if ($token == '(') {
            $subtrees[] = buildTree($lexer, $level);
        } elseif ($token == ')') {
            return buildNode($markers, $subtrees);
        } else {
            $markers[] = $token;
        }
    }

    return buildNode($markers, $subtrees);
}

function buildNode($markers, $subtrees)
{
    if (count($markers) && count($subtrees)) {
        return [$markers[0], $subtrees];
    } elseif (count($subtrees)) {
        return $subtrees;
    } else {
        return $markers;
    }
}

class Lexer
{
    private $data;

    private $matches;

    private $index = -1;

    public function __construct($data)
    {
        $this->data = $data;
        preg_match_all('/[\w]+|\(|\)/', $data, $matches);
        $this->matches = $matches[0];
    }

    public function nextToken()
    {
        $index = ++$this->index;
        if (isset($this->matches[$index]) === false) {
            return false;
        }
        return $this->matches[$index];
    }
}

输出

Array
(
    [0] => Array
        (
            [0] => S
            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => NP
                            [1] => I
                        )

                    [1] => Array
                        (
                            [0] => VP
                            [1] => Array
                                (
                                    [0] => Array
                                        (
                                            [0] => VP
                                            [1] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [0] => V
                                                            [1] => shot
                                                        )

                                                    [1] => Array
                                                        (
                                                            [0] => NP
                                                            [1] => Array
                                                                (
                                                                    [0] => Array
                                                                        (
                                                                            [0] => Det
                                                                            [1] => an
                                                                        )

                                                                    [1] => Array
                                                                        (
                                                                            [0] => N
                                                                            [1] => elephant
                                                                        )

                                                                )

                                                        )

                                                )

                                        )

                                    [1] => Array
                                        (
                                            [0] => PP
                                            [1] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [0] => P
                                                            [1] => in
                                                        )

                                                    [1] => Array
                                                        (
                                                            [0] => NP
                                                            [1] => Array
                                                                (
                                                                    [0] => Array
                                                                        (
                                                                            [0] => Det
                                                                            [1] => my
                                                                        )

                                                                    [1] => Array
                                                                        (
                                                                            [0] => N
                                                                            [1] => pajamas
                                                                        )

                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                )

        )

)

【讨论】:

    猜你喜欢
    • 2018-04-03
    • 2016-12-24
    • 2021-05-10
    • 2018-04-22
    • 2017-09-02
    • 1970-01-01
    • 2010-12-04
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多