Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.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 regex援助_Php_Regex - Fatal编程技术网

Php regex援助

Php regex援助,php,regex,Php,Regex,我正在尝试匹配半动态生成的字符串。所以我可以看看它的格式是否正确,然后从中提取我需要的信息。我的问题是,无论我多么努力地掌握正则表达式,我都无法用我的一生去理解它。即使在所谓的发电机的帮助下 我有两个不同的字符串,如下所示[@img:1234567890]和[@user:1234567890]和[@file:file\u name-with.ext]。像这样的传递字符串旨在传递过滤器,以便可以用链接或更可读的名称替换它们。但是,尽管我可能会再次尝试,但我无法为其中任何一个提供正则表达式 <

我正在尝试匹配半动态生成的字符串。所以我可以看看它的格式是否正确,然后从中提取我需要的信息。我的问题是,无论我多么努力地掌握正则表达式,我都无法用我的一生去理解它。即使在所谓的发电机的帮助下

我有两个不同的字符串,如下所示<代码>[@img:1234567890]和
[@user:1234567890]
[@file:file\u name-with.ext]
。像这样的传递字符串旨在传递过滤器,以便可以用链接或更可读的名称替换它们。但是,尽管我可能会再次尝试,但我无法为其中任何一个提供正则表达式

<pre>
<?php

    $subj = 'An image:[@img:1234567890], a user:[@user:1234567890] and a file:[@file:file_name-with.ext]';
    preg_match_all('~(?<match>\[@(?<type>[^:]+):(?<value>[^\]]+)\])~',$subj,$matches,PREG_SET_ORDER);
    foreach ($matches as &$arr) unset($arr[0],$arr[1],$arr[2],$arr[3]);
    print_r($matches);

?>
</pre>

我正在寻找以下格式:
[@word:][/code>,其中我将从字符串中去掉[,],@,和word,这样我就可以相应地将查询转到我的数据库中,无论它是什么,并相应地使用它。只是正则表达式的一部分让我踌躇不前。

不知道你所说的生成器是什么意思。我总是使用在线匹配器来查看我的测试用例是否有效@维伦德拉几乎做到了,只是忘了避开
[]
字符

/\[@(\w+):(.*)\]/
您需要以正则表达式delimeter开始和结束,在本例中为“/”字符

然后我们对“[]”进行转义,正则表达式使用它来匹配字符范围,因此使用“[]”

接下来我们匹配一个文字'@'符号

现在我们想保存下一个匹配,以便以后使用,所以我们用
()
将其包围起来

\w
匹配一个
。基本上是任何不是空格、标点或行字符的字符

再次匹配文本

将第二部分也包含在匹配组中可能很有用,这样
(.*)
将多次匹配任何字符,并为您保存它

然后,我们像前面做的那样退出关闭
]

因为听起来您希望稍后在查询中使用匹配项,所以我们可以使用它将匹配项保存到数组中

$pattern = '/\[@(\w+):(.*)\]/';
$subject = '[@user:1234567890]';
preg_match($pattern, $subject, $matches);
print_r($matches);
将输出

array(
    [0] => '[@user:1234567890]', // Full match
    [1] => 'user', // First match
    [2] => '1234567890' // Second match
)

我发现一个特别有用的工具是

您可以尝试以下方法:

/\[@(\w+):([^]]*)\]/
\[
转义
[
字符(另一种解释为字符集);
\w
表示任何“单词”字符,
[^]*
表示任何非
]
字符(避免匹配超过标记的末尾,就像
*
可能的那样)。parens将各种匹配的零件分组,以便您可以在
preg\u replace
中使用
$1
$2
生成替换文本:

echo preg_replace('/\[@(\w+):([^]]*)\]/', '$1 $2', '[@link:abcdef]');

打印
链接abcdef

以下是我要做的

下面是如何使用
preg\u replace\u callback()
函数的一个伪版本:

函数替换\u快捷方式($matches){
全球$用户;
开关(strtolower($matches['type'])){
案例“img”:返回“”;
案例“文件”:返回“”;
//在数组中添加每个用户的id
大小写'user':$users[]=(int)$matches['value'];返回'%s';
默认值:返回$matches['match'];
}
}
$users=array();
$replaceArr=array();
$subj='一个图像:[@img:1234567890],一个用户:[@user:1234567890]和一个文件:[@file:file_name-with.ext];
//转义百分号,以避免以后在vsprintf函数调用中出现复杂情况
$subj=strtr($subj,数组('%'=>'%');
$subj=preg\u replace\u回调(“~(?\[@(?[^:+):(?[^\]+)\]),replace\u快捷方式,$subj);
如果(!空($users)){
//连接到数据库并检查用户
$query=“SELECT`id`、`nick`、`date\u deleted`作为'deleted'不为空”
来自(“.”中的“users”,其中的“id”位于(“.”中。内爆(“,”,$users)。“)”;
//质疑
// ...
//并捕捉结果
而($row=$con->fetch_array()){
//此id在用户数组中的位置:
$idx=数组搜索($row['id'],$users);
$nick=htmlspecialchars($row['nick']);
$replaceArr[$idx]=$row['deleted']?
“{$nick}”:
"";
//删除此密钥以便我们稍后可以检查未找到的id。。。
未设置($users[$idx]);
}
//在这里:
foreach($key=>$value的用户){
$replaceArr[$key]=“用户”。$value.”;
}
//替换$sub中标记为%s的每个用户引用
$sub=vsprintf($sub$replaceArr);
}否则{
//删除我们为vsprintf函数添加的额外百分号
$subj=preg_replace('~%{2}','%',$subj);
}
未设置($query、$row、$nick、$idx、$key、$value、$users、$replaceArr);
echo$sub;

试试
[@(\w+):(.*)]
<代码>$1
$2
将为您提供变量。请注意,您应该使用。如果你在那里更具体一些,那么别人会更容易找到你,也会吸引更多具体的帮助,而不仅仅是那些对神秘标题好奇的人。避免重新列出标签、多余的求助请求、毫无疑问的问号。quote unquote生成器可通过google找到,您可以在其中输入要匹配的字符串,然后使用它生成正则表达式。哪一个不是从我收集的信息中得到的,或者它们只是专门匹配你给的字符串,除此之外几乎没有玩的空间。为了分别得到1美元和2美元,我会使用preg_match,preg_replace,其他?如果你有什么建议?@chris为
preg\u match
添加了一节,这是一个很好的观点,我甚至还没有考虑带倍数的字符串。你可能还想使用
preg\u replace\u callback()
重新格式化这些值,而不是用
preg\u match\u all()
捕捉它们。
Array
(
    [0] => Array
        (
            [match] => [@img:1234567890]
            [type] => img
            [value] => 1234567890
        )

    [1] => Array
        (
            [match] => [@user:1234567890]
            [type] => user
            [value] => 1234567890
        )

    [2] => Array
        (
            [match] => [@file:file_name-with.ext]
            [type] => file
            [value] => file_name-with.ext
        )

)
function replace_shortcut($matches) {
    global $users;
    switch (strtolower($matches['type'])) {
        case 'img'  : return '<img src="images/img_'.$matches['value'].'jpg" />';
        case 'file' : return '<a href="files/'.$matches['value'].'" target="_blank">'.$matches['value'].'</a>';
        // add id of each user in array
        case 'user' : $users[] = (int) $matches['value']; return '%s';
        default : return $matches['match'];
    }
}

$users = array();
$replaceArr = array();

$subj = 'An image:[@img:1234567890], a user:[@user:1234567890] and a file:[@file:file_name-with.ext]';
// escape percentage signs to avoid complications in the vsprintf function call later
$subj = strtr($subj,array('%'=>'%%'));
$subj = preg_replace_callback('~(?<match>\[@(?<type>[^:]+):(?<value>[^\]]+)\])~',replace_shortcut,$subj);

if (!empty($users)) {

    // connect to DB and check users
    $query = "  SELECT `id`,`nick`,`date_deleted` IS NOT NULL AS 'deleted'
                FROM `users` WHERE `id` IN ('".implode("','",$users)."')";
    // query
    // ...
    // and catch results
    while ($row = $con->fetch_array()) {
        // position of this id in users array:
        $idx = array_search($row['id'],$users);
        $nick = htmlspecialchars($row['nick']);
        $replaceArr[$idx] = $row['deleted'] ?
            "<span class=\"user_deleted\">{$nick}</span>" :
            "<a href=\"users/{$row['id']}\">{$nick}</a>";
        // delete this key so that we can check id's not found later...
        unset($users[$idx]);
    }
    // in here:
    foreach ($users as $key => $value) {
        $replaceArr[$key] = '<span class="user_unknown">User'.$value.'</span>';
    }
    // replace each user reference marked with %s in $subj
    $subj = vsprintf($subj,$replaceArr);

} else {

    // remove extra percentage signs we added for vsprintf function
    $subj = preg_replace('~%{2}~','%',$subj);

}
unset($query,$row,$nick,$idx,$key,$value,$users,$replaceArr);

echo $subj;