Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/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,这可能是棘手的,容易的或不可能的。。。我不确定 我有一个域名列表,我正试图将它们与“title”标签中的网站名称尽可能地匹配 例如 Domain: www.yahoo.com Title: Yahoo! Result: Yahoo! Domain: www.thegreenpages.com Title: Welcome to The Green Pages. Result: The Green Pages Domain: www.experts-exchange.com: Title:

这可能是棘手的,容易的或不可能的。。。我不确定

我有一个域名列表,我正试图将它们与“title”标签中的网站名称尽可能地匹配

例如

Domain: www.yahoo.com Title: Yahoo! Result: Yahoo! Domain: www.thegreenpages.com Title: Welcome to The Green Pages. Result: The Green Pages Domain: www.experts-exchange.com: Title: Experts Exchange - The #1 resource on the web for solving technology problems. Result: Experts Exchange 域名:www.yahoo.com 标题:雅虎! 结果:雅虎! 域名:www.thegreenpages.com 标题:欢迎来到绿页。 结果:绿页 域名:www.experts-exchange.com: 标题:专家交流-网络上解决技术问题的#1资源。 结果:专家交流 所以你可以看到这里的问题。我需要考虑实例、空格和任何域特殊字符。我还需要捕捉任何特殊的角色,如!在雅虎!但不是一个句号,它只是一个句子的结尾,或者你能想到的任何东西

有道理吗

在PHP中

我真的,真的很讨厌这些类型的模式匹配问题:)

除非你认真地限制问题的范围,否则我会说这是不可能的

title属性可以包含任何人类语言中的任意字符串(符号、外来字符、“smart”之类的,随便你怎么说)。正则表达式如何才能足够聪明地捕捉到相关部分?你能用自己的话正式定义相关部分吗


正则表达式在应用于语言时很糟糕,甚至更复杂的系统在应用于人类语言时也很糟糕

我不确定你是否能想出一个模式来解决你在遇到这样的问题时可能遇到的所有可能性。标题标签可能是完全随机的文本,根本不匹配

例如,这里有一个随机的网站,我从谷歌随机搜索中挑选出来。网站域名是“plus2net.com”,标题是(显然是为了搜索引擎优化)“PHP HTML MySQL文章教程,免费脚本和编程论坛”。你会如何将这两件事联系起来?理论上,您可以使用类似的方法来进行某种统计分析,但我认为使用regexp来解决这个问题是错误的方法


我会重新考虑这个问题。你想完成什么?如果您只是想将域名列表和标题标记关联起来,难道您不能编写一个快速脚本,从您拥有的域名列表中刮取标题标记并获得准确的数据吗?

您可以基于域名构建一个正则表达式,例如:

t\s*h\s*e\s*g\s*r\s*e\s*e\s*n\s*p\s*a\s*g\s*e\s*s
这将匹配不区分大小写模式下的绿色页面


编辑下面是一个如何构建此类正则表达式的示例:

$data = array(
    array('yahoo', 'Yahoo!'),
    array('thegreenpages', 'Welcome to The Green Pages.'),
    array('experts-exchange', 'Experts Exchange - The #1 resource on the web for solving technology problems.')
);

foreach ($data as $item) {
    $domain = preg_split('/(.)/', $item[0], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
    foreach ($domain as $key => $chr) {
        if ($chr == '-') {
            unset($domain[$key]);
        }
    }
    $pattern = '/'.implode('[\s-]*', $domain).'!?/i';
    preg_match($pattern, $item[1], $match);
    var_dump($match[0]);
}

您的域列表是否已修复?如果是这样,你能为每个域构建正则表达式吗

显然,你可以相当简单地去掉这个域,但正如Tomalak所说,除非问题域受到更大的限制,否则它实际上是一个相当复杂的计算问题

从一个域中,您需要去掉这些单词,对于这些单词,您需要一个参考词典(或每种语言一个),以及某种类型的单词匹配,可能是某种类型的对潜在匹配的投票。不过,如果没有一个更具体的问题域,这不太可能是准确的

了解更多您想要实现的目标可能会更好。

尝试以下代码:

$sites = array(
    array('domain' => 'www.yahoo.com', 'title' => 'Yahoo!'),
    array('domain' => 'www.thegreenpages.com', 'title' => 'Welcome to The Green Pages.'),
    array('domain' => 'www.experts-exchange.com', 'title' => 'Experts Exchange - The #1 resource on the web for solving technology problems.'),
);

foreach ($sites as $idx => $site) {
    $domain = preg_replace('/^www\./i', '', $site['domain']);
    $domain = preg_replace('/\.(com|net|org|info|us)$/i', '', $domain);

    $expression = '/';
    for ($i = 0; $i < strlen($domain); $i++) {
        $char = $domain[$i];
        $expression .= $char . (ctype_alpha($char) ? '' : '?');
        $expression .= '\s*';
    }
    $expression .= '/i';

    preg_match($expression, $site['title'], $matches);
    $sites[$idx]['name'] = $matches[0];
}
无论怎样,您都必须调整脚本,直到正确为止,但这是一个开始。

我认为这至少是一个三步过程。
  • 删除标题和url中的标点符号
  • 拆分Url(如有必要)
  • 通过与标题进行比较,使用url查找正确的大小写
'www.thegreenpages.com''欢迎来到绿色页面。'greenpages'
“绿皮书”#删除标点符号
“绿页”“绿页”#搜索结果
“www.experts-exchange.com”“专家交流-第1号决议”“专家交流”
“专家交换”“专家交换1个资源”#删除标点符号
#“专家交流”“专家交流”#搜索结果
“www.yahoo.com”“雅虎!”“雅虎
“yahoo”“yahoo”#删除标点符号
#“雅虎”“雅虎”#搜索结果

#哎哟,省去了感叹号
,谢谢您的回复!我意识到这永远不会100%的匹配。我只是在寻找一些能增加我找到东西的机会的东西。如果什么都没有找到,那我就不在乎那个网站了!谢谢各位。今晚我将开始尝试这些解决方案,谢谢我从未听说过levenshtein函数。。。我会查出来的哦,我已经放弃了域名和标题标签,我正在寻找比这更深一点的东西——但我不能透露;)我认为Levenshtein距离不会有多大帮助。因为它只是描述了两个序列的差异量。零差异将是理想的。但是如果没有完美的匹配呢?添加一个阈值以获得下一个最佳匹配?@Gumbo完全正确。如果多个标题具有相同的Levenshtein距离,您还需要关于如何操作的规则。“Yahood”或“Yahoo”是否匹配(两者的距离均为1)。确定规则应该是什么是一个基于各种输入的尝试和错误的事情。同意所有人。我并不期望levenshtein是一个实际的解决方案,我只是把它作为一个不同的比较启发式方法的例子。这绝对是个棘手的问题。
Array
(
    [0] => Array
        (
            [domain] => www.yahoo.com
            [title] => Yahoo!
            [name] => Yahoo
        )

    [1] => Array
        (
            [domain] => www.thegreenpages.com
            [title] => Welcome to The Green Pages.
            [name] => The Green Pages
        )

    [2] => Array
        (
            [domain] => www.experts-exchange.com
            [title] => Experts Exchange - The #1 resource on the web for solving technology problems.
            [name] => Experts Exchange 
        )
) 
'www.thegreenpages.com'    'Welcome to The Green Pages.'  'The Green Pages'
    'thegreenpages'                                       # remove punctuation
   'the green pages'    <= 'Welcome to The Green Pages'   # split url (if necessary)
                        =>            'The Green Pages'   # result of search

'www.experts-exchange.com'    'Experts Exchange - The #1 res ...'  'Experts Exchange'
    'experts exchange'        'Experts Exchange   The  1 res    '  # remove punctuation
#   'experts exchange'     <= 'Experts Exchange   The  1 res    '  # split url
                           => 'Experts Exchange'                   # result of search

'www.yahoo.com'    'Yahoo!'  'Yahoo!'
    'yahoo'        'Yahoo'   # remove punctuation
#   'yahoo'     <= 'Yahoo'   # split url (if necessary)
                => 'Yahoo'   # result of search
# whoops left off the exclamation point