你怎么逃避这个正则表达式?

时间:2012-10-13 11:08:58

标签: sql regex postgresql

我正在寻找

  

" House M.D。" (2004)

之后的任何事情。我已经尝试了where id~'"House M\.D\." \(2004\).*';并且没有匹配

这有效id~'.*House M.D..*2004.*';,但有点慢。

3 个答案:

答案 0 :(得分:4)

我怀疑你是在一个较旧的PostgreSQL版本,默认情况下以非标准兼容的C-escape模式解释字符串,因此反斜杠被视为转义并被消耗掉。试试SET standard_conforming_strings = 'on';

根据字符串常量的lexical structure文档,您可以:

  • 确保standard_conforming_strings已启用,在这种情况下,您必须将任何单引号加倍(即'变为'')但反斜杠不会被视为转义:

    id ~ '"House M\.D\." \(2004\)'

  • 使用非标准的PostgreSQL特定E''语法并加倍反斜杠:

    id ~ E'"House M\\.D\\." \\(2004\\)'

PostgreSQL 9.1及以上版本默认将standard_conforming_strings设置为on;见the documentation

在测试代码之后,您应该在旧版本中打开它,因为它将使以后的更新变得更加容易。您可以在postgresql.conf,每个用户级别ALTER ROLE ... SET,每个数据库级别ALTER DATABASE ... SET或会话级SET standard_conforming_strings = on上全局启用它。使用SET LOCAL在事务范围内设置它。

答案 1 :(得分:2)

看起来你的正则表达式是正确的

http://sqlfiddle.com/#!12/d41d8/113

答案 2 :(得分:0)

CREATE OR REPLACE FUNCTION public.regexp_quote(IN TEXT) 
  RETURNS TEXT 
  LANGUAGE plpgsql 
  STABLE 
AS $$ 
/******************************************************************************* 
 * Function Name: regexp_quote 
 * In-coming Param: 
 *   The string to decoded and convert into a set of text arrays. 
 * Returns: 
 *   This function produces a TEXT that can be used as a regular expression 
 *   pattern that would match the input as if it were a literal pattern. 
 * Description: 
 *   Takes in a TEXT in and escapes all of the necessary characters so that 
 *   the output can be used as a regular expression to match the input as if 
 *   it were a literal pattern. 
 ******************************************************************************/ 
BEGIN 
  RETURN REGEXP_REPLACE($1, '([[\\](){}.+*^$|\\\\?-])', '\\\\\\1', 'g'); 
END; 
$$ 

测试:

SELECT regexp_quote('"House M.D." (2004)'); -- produces: "House M\\.D\\." \\(2004\\)