Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP从单词数组中查找字符串中的非连续单词组合_Php_Regex - Fatal编程技术网

使用PHP从单词数组中查找字符串中的非连续单词组合

使用PHP从单词数组中查找字符串中的非连续单词组合,php,regex,Php,Regex,我正在寻找一种方法,从$length的$pattern中的$search的任意组合的(可能)非连续匹配模式字符串中返回起始位置和匹配模式 在我的示例中,查找数字为单词的电话号码 $subject = "hello my name is inigo montoya you killed my father please call me at eight zero zero five five five one to three four prepare to die" $search = arr

我正在寻找一种方法,从
$length
$pattern
中的
$search
的任意组合的(可能)非连续匹配模式字符串中返回起始位置和匹配模式

在我的示例中,查找数字为单词的电话号码

$subject = "hello my name is inigo montoya you killed my father please call me at eight zero zero five five five one to three four prepare to die"

$search = array("zero", "one", "two", "to", "too" "three", "four", "five", "six", "seven", "eight", "nine")

$length = 10;

$result = jedi_find_trick($subject,$search,$length);
$result
设置为数组:

$result[0]["start"] = 70
$result[0]["match"] = "eight zero zero five five five one to three four"
$result[1] ... 
生成所有可能的
$search
组合是我的目标,但我觉得有一个更优雅的解决方案,谢谢你的建议


根据@chris85的建议,这似乎是一个很好的起点:

$subject = 'hello my name is inigo montoya you killed my father please call me at eight zero zero five five five one to three four or too oh five seven seven seven five one one one prepare to die';
$search = array('zero','oh','one','two','too','to','three','four','five','six','seven','eight','nine','hundred','thousand');
$replace = array('0','0','1','2','2','2','3','4','5','6','7','8','9','00','000');
$length = 10;

$result = jedi_find_trick($subject,$search,$replace,10);

$result = jedi_find_trick($subject,$search,$replace,$length);

print_r($result);

function jedi_find_trick($subject,$search,$replace,$length) {

    preg_match_all('/(\h*(' . implode('|', $search) . ')\h*){10}/', $subject, $numbers);

    foreach($numbers[0] as $match) {

        $number = str_replace($search,$replace,$match);
        $number = str_replace(' ', '', $number);
        $number = ' ' . $number . ' ';
        $subject = str_replace($match,$number,$subject);

    }

    return $subject;
}
返回:

hello my name is inigo montoya you killed my father please call me at 8005551234 or 2057775111 prepare to die
使用
str_replace()
“too”必须在“to”之前的
$search
中,否则将以“2o”结束。一些尊重preg_replace()的单词边界应该清理干净。

类似这样的东西:

$subject = 'hello my name is inigo montoya you killed my father please call me '
         . 'at eight zero zero five five five one to three four prepare to die';

$search = ['zero', 'one', 'two', 'to', 'too', 'three', 'four', 'five', 'six',
           'seven', 'eight', 'nine'];

$length = 10;

function jedi_find_trick($search, $subject, $length, $sep = ' ', $septype = 0) {
    // quote special characters in the search list
    $search = array_map(function ($i) { return preg_quote($i, '~'); }, $search);
    // quote the separator when it is a literal string
    if ($septype === 0) $sep = preg_quote($sep, '~');

    // build the pattern
    $altern = '(?:' . implode('|', $search) . ')';

    $format = '~(?:%1$s|\A)(%2$s'
            . ($length<2 ? '': '(?:%1$s%2$s){%3$d}')
            . ')(?=%1$s|\z)~';

    $pattern = sprintf($format, $sep, $altern, $length - 1);

    if (preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE))
        return $matches[1];

    // return an empty array if there is no match
    return [];
}

print_r(jedi_find_trick($search, $subject, $length));
print_r(jedi_find_trick($search, $subject, 8, '\h+', 1));
$subject='你好,我叫伊尼戈·蒙托亚,你杀了我父亲,请打电话给我'
. '八零零五五五一到三四准备死",;
$search=['0'、'1'、'2'、'to'、'too'、'3'、'4'、'5'、'6',
‘七’、‘八’、‘九’;
$length=10;
函数jedi_find_技巧($search,$subject,$length,$sep='',$septype=0){
//在搜索列表中引用特殊字符
$search=array_-map(函数($i){return preg_-quote($i,~');},$search);
//当分隔符是文字字符串时,将其引为引号
如果($septype==0)$sep=preg_quote($sep,“~”);
//构建模式
$altern='(?:'。内爆('|',$search)。');
$format='~(?:%1$s |\A)(%2$s'

($length可能是这样的,你说的“非连续”是什么意思
$search
值在
$subject
中的顺序可能与数组中的顺序不同。是的,我的示例中没有这样的顺序。在草堆中找到的任何单词都将被捕获。
$length
部分是什么?怎么样?然后
stru替换你的值,因为你知道它们是电话号码?