使用PHP从存储在ASTERISK数据库中的规则中提取正则表达式
我试图创建一种带有动态变量的正则表达式 与PHP一起使用一些存储在数据库表中的预定义值,以便 验证星号中的拨号字符串。 数据库中有 用于传出规则的表,每个用户可以创建该表以应用于其扩展 PHP中的变量可以如下所示:使用PHP从存储在ASTERISK数据库中的规则中提取正则表达式,php,mysql,sql,regex,asterisk,Php,Mysql,Sql,Regex,Asterisk,我试图创建一种带有动态变量的正则表达式 与PHP一起使用一些存储在数据库表中的预定义值,以便 验证星号中的拨号字符串。 数据库中有 用于传出规则的表,每个用户可以创建该表以应用于其扩展 PHP中的变量可以如下所示: $N = '[23456789]'; $Z = '\d*'; //(any digit, any occurrence) $X = '[0-9]'; $x = '[0-9]'; +----+-----------+-------+-------------+------------
$N = '[23456789]';
$Z = '\d*'; //(any digit, any occurrence)
$X = '[0-9]';
$x = '[0-9]';
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
| id | extension | order | description | ruledigits | ruletype | subtract | prefix | suffix |
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
| 1 | 1005 | 1 | | 9XX | Block | null | null | null |
| 2 | 1005 | 2 | | 302NXXXXXX | Mod | null | 1 | null |
| 3 | 2005 | 1 | | 00Z | Mod | 2 | 011 | null |
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
规则中的数字将被视为数字本身
规则中的符号将被视为符号本身(数据库中仅接受*和#作为符号)
表格是这样的:
$N = '[23456789]';
$Z = '\d*'; //(any digit, any occurrence)
$X = '[0-9]';
$x = '[0-9]';
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
| id | extension | order | description | ruledigits | ruletype | subtract | prefix | suffix |
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
| 1 | 1005 | 1 | | 9XX | Block | null | null | null |
| 2 | 1005 | 2 | | 302NXXXXXX | Mod | null | 1 | null |
| 3 | 2005 | 1 | | 00Z | Mod | 2 | 011 | null |
+----+-----------+-------+-------------+------------+----------+-----------+--------+--------+
因此,如果1005分机拨打908(没有更多的数字),该呼叫应该被阻止
根据行动领域。如果1005分机拨302555(不再
数字),该呼叫将以数字1作为前缀
Iif 1005分机拨00325698289115(国际),该呼叫将不会
me根据规则#3进行了修改,因为该规则仅适用于EXT 2005,所以
呼叫将在拨号至服务器时发送
如果最后一次电话是在2005年打的,号码会符合规定,
因为它以00开头,Z是任何数字,所以任何电流都是。因此,拨出的号码将从开头减去“2”位,然后在发送到中继线之前加上前缀“011”
我认为这里的重要领域是规则数字(当然还有扩展),
PHP将使用它作为每个EXT的规则数组
仅当满足条件时才可读取
条件是这样的,虽然这只代表
1规则和案例:
if(preg_match("/^1$N$X$N(555)$Z/", $number))
{
// $number format matches
echo "yes"; // apply the action according the table
}
else
{
echo "no"; // no action applied, proceed with the call.
}
我需要的条件,必须在飞行中创建的实际情况
调用(通过php脚本请求访问数据库)发现
这里不仅有1条规则,还分别为该扩展创建了一些规则
如何制作或设计可以访问数据库“规则”的通用函数
表和数组调用方下创建的所有条件的组
为了将它们应用到实际通话中而进行的扩展
注:字段
“规则”表中的“规则数字”仅接受以下字符:
N、 Z、*、#或任何数字。以下是我个人如何使用MySQL数据构建用于检查数据的正则表达式模式:
//Simplified array
$dbResults = array(
array(
'id' => 1,
'extension' => 1005,
'order' => 1,
'description' => 'rule 1',
'ruledigits' => '9XX',
'prefix' => null,
'ruletype' => 'Block'
),
array(
'id' => 2,
'extension' => 1005,
'order' => 2,
'description' => 'rule 2',
'ruledigits' => '302NXXXXXX',
'prefix' => 1,
'ruletype' => 'Mod'
),
array(
'id' => 3,
'extension' => 2005,
'order' => 3,
'description' => 'rule 3',
'ruledigits' => '00Z',
'prefix' => '001',
'ruletype' => 'Mod'
)
);
$regexParts = array(
'N' => '[2-9]'
,'Z' => '\d*'
,'X' => '\d'
,'x' => '\d'
);
//Static test vars
$userExt = 1005;
$dialTests = array('00325698289115','908','3025555555');
echo 'Testing user extension: '.$userExt;
echo '<br /><br />';
//This loop is for testing purposes only, the contents are all the live system would use
foreach($dialTests as $testNo)
{
$actionTaken = 'None';
//By default, if nothing happens, make sure the final number is the original one we saw
$finalNo = $testNo;
foreach($dbResults as $row)
{
if($userExt != $row['extension']) continue;//If it's not the right extension, skip the rest of this loop iteration's code and move on to the next row
$regex = '';
$tokens = str_split($row['ruledigits']);//Turn the string into an array, so we can parse each character individually
foreach($tokens as $token)
{
if(isset($regexParts[$token])) $regex .= $regexParts[$token];//If the letter has a special meaning, use that
else $regex .= $token;//else just throw that exact letter/number in
}
if(preg_match('#^'.$regex.'$#',$testNo)>0)
{
$actionTaken = $row['ruletype'];//Log what action has been taken
if($actionTaken=='Mod')
{
$finalNo = $row['prefix'].$testNo;//Do the mod action
}
else if($actionTaken=='Block')
{
$finalNo = false;//Nullify the final number, so we know to block the call later on
}
}
}
//Here we just dump some info for testing purposes
echo $testNo.': Action taken = '.$actionTaken;
if($actionTaken=='Block') echo ' - Call terminated.';
if($actionTaken=='Mod') echo ' - New number = '.$finalNo;
echo '<hr />';
}
//简化数组
$dbResults=array(
排列(
'id'=>1,
“扩展”=>1005,
“顺序”=>1,
'说明'=>'规则1',
'ruledigits'=>'9XX',
'前缀'=>null,
'规则类型'=>'块'
),
排列(
'id'=>2,
“扩展”=>1005,
“顺序”=>2,
'说明'=>'规则2',
'ruledigits'=>'302nxxxx',
'前缀'=>1,
'规则类型'=>'模块'
),
排列(
'id'=>3,
“扩展”=>2005年,
“顺序”=>3,
'说明'=>'规则3',
'ruledigits'=>'00Z',
'前缀'=>'001',
'规则类型'=>'模块'
)
);
$regexpart=array(
“N”=>“[2-9]”
,'Z'=>'\d*'
,'X'=>'\d'
,'x'=>'\d'
);
//静态测试变量
$userExt=1005;
$dialTests=数组('00325698289115'、'908'、'30255555');
echo“测试用户扩展名:”。$userExt;
回音“
”;
//此循环仅用于测试目的,内容是实时系统将使用的所有内容
foreach($dialTests作为$testNo)
{
$actiontaked='None';
//默认情况下,如果什么都没有发生,请确保最终的数字是我们看到的原始数字
$finalNo=$testNo;
foreach($dbResults作为$row)
{
如果($userExt!=$row['extension'])继续;//如果它不是正确的扩展,请跳过此循环迭代的其余代码并转到下一行
$regex='';
$tokens=str_split($row['ruledigits']);//将字符串转换为数组,这样我们就可以单独分析每个字符
foreach($tokens作为$token)
{
if(isset($regexParts[$token])$regex.=$regexParts[$token];//如果字母有特殊含义,请使用
else$regex.=$token;//否则只需输入准确的字母/数字即可
}
如果(preg#u match(“#^”。$regex.$#,$testNo)>0)
{
$actiontaked=$row['ruletype'];//记录已采取的操作
如果($actiontaked=='Mod')
{
$finalNo=$row['prefix']。$testNo;//执行mod操作
}
else if($actiontaked=='Block')
{
$finalNo=false;//使最终号码为空,这样我们就知道以后要阻止呼叫
}
}
}
//这里我们只是为了测试目的而转储一些信息
echo$testNo.':Action-taked='.$actiontaked;
如果($actiontaked=='Block')回显'-呼叫终止';
如果($actiontaked=='Mod')echo'-newnumber='.$finalNo;
回声“
”;
}
查看输出演示(单击运行/F9)您可以使用星号实时体系结构和正确的视图来匹配扩展表 或者您可以将mysql查询与REGEXP/RLIKE构造一起使用 通过使用简单的重写,您可以轻松地将星号regexp更改为常规regexp,如
'.' -> '.*'
'X' -> '[0-9]'
etc好的,首先,这需要简化。Waaay有太多的背景信息,感谢您尝试确保我们了解正在发生的事情,但这会吓跑人们。我已经通读了它,它似乎基本上是,我如何从存储在数据库中的规则构建正则表达式-如果是这样,请给我们示例db/表结构和内容(少量),加上一些测试用例等。简明扼要。好的,根据更新,您可能希望解析
302nxxxx
以302$N$X$X$X$X$X$X
(即302[23456789][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][code>或简化为:302 2-9][6}
)?类似于00Z
和9XX
(或其他)。然后,如果该模式匹配,请使用ruletype
确定发生了什么。确切地每次通话(拨号串)