PostgreSQL正则表达式边界?

时间:2010-09-29 20:41:33

标签: regex postgresql word-boundary

PostgreSQL是否支持\b

我正在尝试\bAB\b,但它与任何内容都不匹配,而(\W|^)AB(\W|$)则可以。这两个表达式基本相同,不是吗?

3 个答案:

答案 0 :(得分:71)

PostgreSQL使用\m\M\y\Y作为字边界:

\m   matches only at the beginning of a word
\M   matches only at the end of a word
\y   matches only at the beginning or end of a word
\Y   matches only at a point that is not the beginning or end of a word 

请参阅手册中的Regular Expression Constraint Escapes

还有[[:<:]][[:>:]],它们匹配单词的开头和结尾。来自the manual

  

括号表达式有两种特殊情况:括号表达式[[:<:]][[:>:]]是约束,分别在单词的开头和结尾处匹配空字符串。一个单词被定义为一个单词字符序列,既不是单词字符,也不是单词字符。单词字符是alnum字符(由ctype定义)或下划线。这是一个扩展,与POSIX 1003.2兼容但未指定,并且在用于移植到其他系统的软件中应谨慎使用。下面描述的约束转义通常是可取的(它们不再标准,但肯定更容易键入)。

答案 1 :(得分:14)

一个简单的例子

select * from table_name where column ~* '\yAB\y';

这将匹配AB ab ab - text text ab text AB text-ab-text text AB text ...

但你必须使用:

select * from sometable where name ~* '\\yAB\\y';

如果你有standard_conforming_strings标志  设为OFF。请注意双斜杠
您可以手动设置:

set standard_conforming_strings=on;

然后:select * from table_name where column ~* '\yAB\y';应该有用。

答案 2 :(得分:2)

文字中的确切单词搜索:

我遇到了以下问题。

我想搜索所有在标题中都有'cto'作为确切单词的联系人,但是在结果中得到的结果标题中有'director',我使用了以下查询

select * from contacts where title ~* '\\ycto\\y';

~   Matches regular expression, case sensitive
~*  Matches regular expression, case insensitive    

我还尝试将通配符周围的whitspace作为'%cto%',它与包含'cto'的文本匹配,获得的结果类似于'vp,cto和manger',但没有得到精确标题为'cto'的结果。

我希望结果中的'vp,cto和manger'和'cto',但结果中不是'导演'

以下为我工作

<?php

use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;

# http://stackoverflow.com/a/3352564/283851
# https://gist.github.com/XzaR90/48c6b615be12fa765898

# Forked from https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2

/**
 * Recursively delete a directory and all of it's contents - e.g.the equivalent of `rm -r` on the command-line.
 * Consistent with `rmdir()` and `unlink()`, an E_WARNING level error will be generated on failure.
 *
 * @param string $source absolute path to directory or file to delete.
 * @param bool   $removeOnlyChildren set to true will only remove content inside directory.
 *
 * @return bool true on success; false on failure
 */
function rrmdir($source, $removeOnlyChildren = false)
{
    if(empty($source) || file_exists($source) === false)
    {
        return false;
    }

    if(is_file($source) || is_link($source))
    {
        return unlink($source);
    }

    $files = new RecursiveIteratorIterator
    (
        new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::CHILD_FIRST
    );

    //$fileinfo as SplFileInfo
    foreach($files as $fileinfo)
    {
        if($fileinfo->isDir())
        {
            if(rrmdir($fileinfo->getRealPath()) === false)
            {
                return false;
            }
        }
        else
        {
            if(unlink($fileinfo->getRealPath()) === false)
            {
                return false;
            }
        }
    }

    if($removeOnlyChildren === false)
    {
        return rmdir($source);
    }

    return true;
}