【发布时间】:2014-03-22 06:56:40
【问题描述】:
我正在学习 PHP,并在文本文件脚本中构建了一个小搜索。以下是事件链:
- 打开文本文件
- 从每一行创建数组
- 如果提交了表单,则将发布数据放入一个函数中,该函数运行一个正则表达式来查找部分字符串或单词,如果匹配,则所有条目都会在代码中替换为一个类,并带有一些 CSS。
我的问题是:
如果我有这样的句子:
汤姆手里拿着相机。我也是地板上的摄像头。
然后搜索“am”,它会搜索并找到相机,并将其替换为 span 类。然后它找到 "am" 并在 Camera 中替换它两次,并替换它自己。
这是我的代码:
//---- Puts Array into or responds with error
$lines = file($filename, FILE_IGNORE_NEW_LINES);
if ( !is_array($lines) ) {
echo 'Cannot create array from file';
}
//---- Scans and Displays Lines
$submission = $_GET['Search'];
function scanLines($lines, $submission) {
foreach($lines as $line) {
if(strpos($line,$submission)!== false){
preg_match_all("/\b[a-z]*".preg_quote($submission)."[a-z]*\b/i", $line, $matches);
$i = 0;
foreach($matches[$i] as $match) {
$line = str_replace($match, '<span class="highlight">'.$match.'</span>', $line);
$i++;
}
echo $line;
}
}
}
示例的直接链接:http://www.effectivemark.com/testphp/
我的问题是:过滤掉相机中“am”的最佳方法是什么,所以它不会添加带有 span 标签的字符串,如下所示:
<span class="highlight">c<span class="highlight">am</span>era</span>
更新代码:
//---- Scans and Displays Lines
$submission = $_GET['Search'];
function scanLines($lines, $submission) {
foreach($lines as $line) {
if(strpos($line,$submission)!== false){
$words = explode(' ', $line);
$i = 0;
$combine = array();
foreach($words as $word) {
if (preg_match("/\b[a-z]*".preg_quote($submission)."[a-z]*\b/i", $word)) {
preg_match_all("/\b[a-z]*".preg_quote($submission)."[a-z]*\b/i", $word, $match);
$matches = '<span class="highlight">' . $match[0][0] . '</span>';
}
else {
$matches = $word;
}
array_push($combine, $matches);
$i++;
}
foreach($combine as $combined) {
echo $combined . ' ';
}
}
}
}
【问题讨论】:
-
您可以通过explode() 将单词排成一行,或者,也许更好的是,使用php.net/manual/sr/function.str-word-count.php 获取它们,然后将整个单词而不是单词部分进行匹配。
-
所以将单词放入数组中,并为所有单词运行此匹配?让我试一试
-
是的,我什至不会使用正则表达式,您可以检查获取值是否为 in_array()?
-
正则表达式解释了部分输入的任何单词。因此,在“Apple”一词中输入“app”将获得全部价值。
-
我将行列数组写为: $words = explode(' ', $line);但是,如果我为每个运行正则表达式,我似乎无法获得正确的逻辑。有什么想法吗?