我将从一个例子开始,因为我不确定我是否能恰当地解释它。
这个问题比较容易的部分(我想虽然我也不明白):
- 取一些字符串,例如“Example”、“DOMNode”、“DOMext”、“DOMElement”
- 和输出“(示例|DOM(节点|正文|元素))'
问题的更复杂部分是从字符串的两端进行匹配
- 取一些字符串,例如“示例”、“数组迭代器”、“递归数组迭代器"、”目录迭代器“、”递归目录迭代器“
- 和输出“(示例|(递归)?(数组|目录)迭代器)'
- 我有一个字符串(模式)列表来匹配主题。
- 我可以简单地将模式与交替(这是我当前的系统)连接起来,但是我想找到一种方法将公共前缀分组到交替组中。
这并不是一个真正的优化,但我一直试图做它作为一个有趣的练习,现在它只是给我一个头痛哈哈。
我试着把每个字符串按字母拆开,匹配每一种可能的组合。
我记不起我在上午做过的所有事情了。我在拼命工作。
我找不到一种方法来获得共同的前缀或存储他们,所以我可以重建他们到一个正则表达式。似乎是一个简单的问题,但我卡住了。
我有一个用下划线分隔字符串的函数:(当你知道如何用下划线分隔前缀时效果很好)
<?php
/**
* separates snake case names into nested hierarchies.
*/
function processArray(array $funcs): array
{
$loop = false;
$current = false;
$newFuncs = [];
foreach ($funcs as $name)
{
$pos = strpos($name, '_');
if ($current and !str_starts_with($name, $current))
{
if ($loop || $pos)
{
$newFuncs[$current] = processArray($newFuncs[$current]);
$loop = false;
}
$current = false;
}
if ($pos)
{
$current = substr($name, 0, $pos + 1);
$newFuncs[$current] ??= [];
$subName = substr($name, $pos + 1);
$newFuncs[$current][] = $subName;
if (strpos($subName, '_'))
{
$loop = true;
}
}
else
{
if ($loop)
{
$newFuncs[$current] = processArray($newFuncs[$current]);
$loop = false;
}
$current = false;
$newFuncs[] = $name;
}
}
return $newFuncs;
}
function getRegex(array $strs): string
{
static $level = 0;
$ret = '(';
foreach ($strs as $key => $value)
{
if (is_array($value))
{
$strs[$key] = (is_string($key)?$key:'').getRegex($value);
}
}
$ret.= implode('|', $strs);
$ret.= ')';
return $ret;
}
$funcs = get_defined_functions()['internal'];
sort($funcs);
$funcs = processArray($funcs);
$getRegex = getRegex($funcs);
//remove isolated groups (groups with only one alternation)
do
{
$getRegex = preg_replace('~\(([a-zA-Z_0-9]+?)\)~', '$1', $getRegex, -1, $count);
}
while ($count);
var_dump($getRegex);
1条答案
按热度按时间guykilcj1#
创建一个完整的正则表达式trie是一个相当复杂的动作。
而且它绝对减少了匹配的时间。
我用一个软件程序做了这个。
只需将字符串放入一个字段,它就会进行解析,然后输出一个trie。
你的样本很容易手工完成,但我不希望那些算法
有利于节目的投放。
当你构造一个trie时,如果可能的话,一定要使用降序方法。
示例、域节点、域文本、域元素
降序(推荐)
Example|DOM(?:(?:Tex|Elemen)t|Node)
升序(不推荐)
DOM(?:(?:Elemen|Tex)t|Node)|Example
示例,数组迭代器,递归数组迭代器,目录迭代器,递归目录迭代器
降序(推荐)
(?:Recursive(?:Director|Arra)|Director|Arra)yIterator|Example
升序(不推荐)
(?:Arra|Director|Recursive(?:Arra|Director))yIterator|Example