在正则表达式中替换

时间:2014-02-11 05:28:16

标签: regex preg-replace preg-match

输入字符串:“此处显示任何字符串或数字字符

插入员工值(nextval('public.scheduled_charges_id_seq'),'shrenik',555,NULL,253,'Rahul')这是我的字符串“

必需输出:“此处显示任何字符串或数字字符

插入员工值(nextval('public.scheduled_charges_id_seq'),'XXX',XXX,NULL,XXX,'XXX')

这是我的字符串“

我试过:([0-9] | \'。* \') 必须匹配给定字符串中的“插入” 想要替换字符串中的机密值从插入到模式中开始应该仅限于嵌入到员工中的大括号(到它结束的位置。你可以帮助我吗?在此先感谢

1 个答案:

答案 0 :(得分:0)

假设insert into employees values( nextval( 'public.scheduled_charges_id_seq' ),已修复且您的查询中没有任何其他函数调用或子查询,那么您可以这样做:

// Set up test string
$statement = "Any string or numeric character appears here

insert into employees values( nextval( 'public.scheduled_charges_id_seq' ),'shrenik', 555, NULL,253,'Rahul') This is my String";

$pieces = preg_split('/\)[, ]/', $statement);
// print_r($pieces);
// $pieces[0] contains everything up to "... id_seq' " 
// $pieces[1] contains all of the fields you want to redact
// $pieces[2] contains everything after the closing )

$pieces[1] = preg_replace('/\'\w+\'|\d+/', 'XXX', $pieces[1]);
// print $pieces[1] . "\n";

$statement = $pieces[0] . ")," . $pieces[1] . ") " . $pieces[2];
print $statement . "\n";

输出:

Any string or numeric character appears here

insert into employees values( nextval( 'public.scheduled_charges_id_seq' ),XXX, XXX, NULL,XXX,XXX) This is my String

已编辑: 回应OP关于未使用preg_split的评论。

您可以使用频率较低的preg_replace_callback,它将第二个参数作为函数回调,它处理匹配数组以生成所需的替换字符串。 preg_replace_callback上的文档可以是found here

$statement = "Any string or numeric character appears here

insert into employees values( nextval( 'public.scheduled_charges_id_seq' ),'shrenik', 555, NULL,253,'Rahul') This is my String";

$statement = 
  preg_replace_callback('/(insert into(?:[^\)]+)\),)(.*)\) /', 
                        function($matches) {
                          return $matches[1] .
                                 preg_replace('/(^|,)[ ]*[^,]+/', '$1 XXX', $matches[2]) .
                                 ') ';
                        },
                        $statement);

print $statement . "\n";

输出与前一个示例相同。

以上两个示例会替换insert查询字符串中的每个字段。

**已编辑:** 已添加以下代码示例以回应OP的评论。

如果您想要排除某些字词(例如NULLNOW()),那么这会让事情复杂化。您可以像下面这样执行此操作,定义一个常量,这是一个以管道分隔的术语字符串,您希望用XXX替换。

$original_statement = 
  "insert into public.scheduled_charges VALUES ( nextval( 'public.scheduled_charges_id_seq' ), 4633, 9085042, 116164, 3, NULL, NULL, NULL, '055    ~..~00~..~140~..~7~..~RNT~..~Jan 1 2014 12:00AM', 875, NULL, 1, '01/01/2014', '12/31/2013', '01/01/2014', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, '01/01/2014', NULL, '01/31/2014', NULL, NULL, 2414, NOW(), 2414, NOW() ) RETURNING id;";

define('IGNORE_TERMS', 'NULL|NOW()');

$replaced_statement = 
  preg_replace_callback('/(insert into(?:[^\)]+)\),)(.*)[ ]*\) /', 
                        function($matches) {
                          return $matches[1] .
                                 preg_replace_callback('/(^|,)([^,]+)/',
                                                       function($matches) {
                                                         $matches[2] = trim($matches[2]);
                                                         if (in_array(strtoupper($matches[2]),
                                                                      explode('|', IGNORE_TERMS))) {
                                                           return $matches[1] . ' ' . $matches[2];
                                                         }
                                                         else {
                                                           return $matches[1] . ' XXX';
                                                         }
                                                       },
                                                       $matches[2]) .
                                 ') ';
                        },
                        $original_statement);

print $original_statement . "\n";
print "\n";
print $replaced_statement . "\n";

这有效,并为您提供您正在寻找的结果。 我并不是说代码很漂亮甚至非常灵活。但是,在这种情况下,它可以为你完成工作。