我需要一些关于正则表达式的帮助。这个概念很简单,但实际的解决方案远远超出了我知道如何弄清楚的任何东西。如果有人能解释我如何达到我想要的效果(并提供任何示例代码的解释(,将不胜感激!
基本上,假设有一个存储以下字符串的数据库表:
'My name is $1. I wonder who $2 is.'
首先,请记住,美元符号数字格式是一成不变的。这不仅仅是这个例子 - 这就是这些通配符的实际存储方式。我希望像下面这样的输入能够返回上面的字符串。
'My name is John. I wonder who Sarah is.'
如何创建一个查询,以这种格式使用通配符进行搜索,然后返回适用的行?我想正则表达式将是最好的方法。请记住,从理论上讲,任何数量的通配符都应该是可以接受的。
现在,这是我现有查询的一部分,它将内容拖出数据库。串联等之所以存在,是因为在单个数据库单元中,有多个由竖线连接的字符串。
AND CONCAT('|', content, '|')
LIKE CONCAT('%|', '" . mysql_real_escape_string($in) . "', '|%')
我需要修改 ^this 行以处理作为查询一部分的变量,同时保持当前效果(垂直条等(。如果正则表达式也考虑了柱线,则可以删除 CONCAT(( 函数。
下面是一个示例字符串,其中包含可能出现在数据库中的串联:
Hello, my name is $1.|Hello, I'm $1.|$1 is my name!
查询应该能够与字符串中的任何这些块匹配,如果存在匹配项,则返回该行。变量$1
应视为通配符。竖线将始终分隔块。
对于MySQL,这篇文章是一个很好的指南,应该会对你有所帮助。正则表达式将是"(\$((\d+("。这是我从文章中撕掉的一个查询:
SELECT * FROM posts WHERE content REGEXP '(\$)(\d+)';
检索数据后,使用此方便的功能:
function ParseData($query,$data) {
$matches=array();
while(preg_match("/(\$)(\d+)/",$query,$matches)) {
if (array_key_exists(substr($matches[0],1),$data))
$query=str_replace($matches[0],"'".mysql_real_escape_string($data[substr($matches[0],1)])."'",$query);
else
$query=str_replace($matches[0],"''",$query);
}
return $query;
}
用法:
$query="$1 went to $2's house";
$data=array(
'1' => 'Bob',
'2' => 'Joe'
);
echo ParseData($query,$data); //Returns "Bob went to Joe's house
如果您对使用 1 美元和 2 美元不感兴趣,并且可以稍微改变一下,您可以看看这个:
http://php.net/manual/en/function.sprintf.php
例如
<?php
$num = 5;
$location = 'tree';
$format = 'There are %d monkeys in the %s';
printf($format, $num, $location);
?>
在数据库中查找条目,则可以使用 LIKE 语句:
SELECT statement FROM myTable WHERE statement LIKE '%$1%'
这将找到包含 $1 的所有语句。我假设要替换的第一个数字始终是 1 美元 - 在这种情况下,通配符的总数是任意的并不重要,因为我们只是在寻找第一个。
PHP 替换有点棘手。你可以做这样的事情:
$count = 1;
while (strpos($statement, "$" . $count)) {
$statement = str_replace("$" . $count, $array[$count], $statement);
}
(我还没有测试过,所以里面可能有错别字,但应该足以给出大致的想法。
一个缺点是,如果字符串中有十个以上的参数要替换,它将失败 - 第一次运行将替换 $10 的前两个字符,因为它正在寻找 $1。
我问了一个不同但相似的问题,我认为解决方案也适用于这个问题。
https://stackoverflow.com/a/10763476/1382779