PostgreSQL正規表現の一般的な機能の概要

PostgreSQL正規表現の一般的な機能の概要

PostgreSQL正規表現の一般的な機能の概要

正規表現は、複雑なデータ処理を必要とするプログラムにとって、間違いなく非常に便利なツールです。この記事では、PostgreSQL のよく使用される正規表現関数とソース コード内のいくつかの関数について説明することに重点を置いています。

通常関連部分のディレクトリ構造

[root@localhost 正規表現]# pwd
/opt/hgdb-core/src/include/regex
[root@localhost 正規表現]# ll
合計40
-rw-r--r--。1 postgres postgres 3490 3月19日 19:00 regcustom.h
-rw-r--r--。1 postgres postgres 1332 3月19日 18:59 regerrs.h
-rw-r--r--。1 postgres postgres 6703 3月19日 19:00 regex.h
-rw-r--r--。1 postgres postgres 2353 3月19日 19:00 regexport.h
-rw-r--r--。1 postgres postgres 16454 3月19日 19:00 regguts.h

正規表現のコンパイル、マッチング、リリース、エラー情報関連のファイルについては後ほど詳しく紹介します

[root@localhost 正規表現]# pwd
/opt/hgdb-core/src/backend/regex
[root@localhost 正規表現]# ll reg*.c
-rw-r--r--。1 postgres postgres 55851 3月19日 19:00 regcomp.c
-rw-r--r--。1 postgres postgres 3671 3月19日 18:59 regerror.c
-rw-r--r--。1 postgres postgres 34873 3月19日 19:00 regexec.c
-rw-r--r--。1 postgres postgres 2123 3月19日 18:59 regfree.c
[root@localhost 正規表現]# 

組み込み関数はregexp.cに実装されています。

[root@localhost adt]# パスワード
/opt/hgdb-core/src/backend/utils/adt
[root@localhost adt]# ll regexp.c
-rw-r--r--。1 postgres postgres 34863 4月12日 02:29 regexp.c
[root@localhost adt]#

組み込み関数の宣言:

/* src/include/catalog/pg_proc.h */

DATA(挿入 OID = 2073 ( 部分文字列 PGNSP PGUID 12 1 0 0 0 fffftfi 2 0 25 "25 25" _null_ _null_ _null_ _null_ _null_ textregexsubstr _null_ _null_ _null_ ));
DESCR("正規表現に一致するテキストを抽出");
DATA(挿入 OID = 2074 ( サブ文字列 PGNSP PGUID 14 1 0 0 0 fffftfi 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ "pg_catalog.substring($1, pg_catalog.similar_escape($2, $3))" _null_ _null_ _null_ ));
DESCR("SQL99 正規表現に一致するテキストを抽出");

DATA(挿入 OID = 2284 ( regexp_replace PGNSP PGUID 12 1 0 0 0 fffftfi 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ textregexreplace_noopt _null_ _null_ _null_ ));
DESCR("正規表現を使用してテキストを置換");
DATA(挿入 OID = 2285 ( regexp_replace PGNSP PGUID 12 1 0 0 0 fffftfi 4 0 25 "25 25 25 25" _null_ _null_ _null_ _null_ _null_ textregexreplace _null_ _null_ _null_ ));
DESCR("正規表現を使用してテキストを置換");

DATA(挿入 OID = 2763 ( regexp_matches PGNSP PGUID 12 1 1 0 0 fffftti 2 0 1009 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_matches_no_flags _null_ _null_ _null_ ));
DESCR("正規表現に一致するすべてのグループを検索");
DATA(挿入 OID = 2764 ( regexp_matches PGNSP PGUID 12 1 10 0 0 fffftti 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_matches _null_ _null_ _null_ ));
DESCR("正規表現に一致するすべてのグループを検索");

DATA(挿入 OID = 2765 ( regexp_split_to_table PGNSP PGUID 12 1 1000 0 0 fffftti 2 0 25 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_table_no_flags _null_ _null_ _null_ ));
DESCR("パターンで文字列を分割");
DATA(挿入 OID = 2766 ( regexp_split_to_table PGNSP PGUID 12 1 1000 0 0 fffftti 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_table _null_ _null_ _null_ ));
DESCR("パターンで文字列を分割");

DATA(挿入 OID = 2767 ( regexp_split_to_array PGNSP PGUID 12 1 0 0 0 fffftfi 2 0 1009 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_array_no_flags _null_ _null_ _null_ ));
DESCR("パターンで文字列を分割");
DATA(挿入 OID = 2768 ( regexp_split_to_array PGNSP PGUID 12 1 0 0 0 fffftfi 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_array _null_ _null_ _null_ ));

パラメータの型と戻り値の型:

postgres=# select oid,typname from pg_type where oid = 25 or oid = 1009;
 oid | タイプ名 
------+---------
  25 | テキスト
 1009 | _テキスト
(2行)

substring(string from pattern) 関数は、POSIX 正規表現パターンに一致する文字列から部分文字列を抽出するメソッドを提供します。一致するものがない場合には NULL を返し、そうでない場合はパターンに一致したテキストの部分を返します。

regexp_replace(source, pattern, replacement [, flags ]) 関数は、POSIX 正規表現パターンに一致する部分文字列を新しいテキストに置き換える機能を提供します。

regexp_matches(string, pattern[, flags ]) 関数は、POSIX 正規表現パターンに一致するすべての部分文字列を含むテキストの配列を返します。
flags パラメータは、関数の動作を変更する 0 個以上の 1 文字のフラグを含むオプションのテキスト文字列です。 g フラグにより​​、文字列内の最初の一致だけでなくすべての一致が検索され、各一致が 1 行で返されます。

regexp_split_to_table(string, pattern[, flags ]) 関数は、POSIX 正規表現パターンを区切り文字として使用して文字列を分割します。返される結果は文字列です。 。

regexp_split_to_array (string, pattern[, flags ]) 関数は regexp_split_to_table と同じように動作しますが、結果をテキスト配列として返します。

具体的な使用方法についてはユーザーマニュアルを参照してください。

src/include/regex/regex.h

regex_t 構造体

/* 一番大事なのは、コンパイルされた RE (というか、そのフロントエンド) */
typedef構造体
{
 int re_magic; /* マジックナンバー */
 size_t re_nsub; /* 部分式の数 */
 long re_info; /* REに関する情報 */
#REG_UBACKREF 000001 を定義します
#REG_ULOOKAHEAD 000002 を定義します
#REG_UBOUNDS 000004 を定義します
#REG_UBRACES 000010 を定義します
#REG_UBSALNUM 000020 を定義します
#REG_UPBOTCH 000040 を定義します
#REG_UBBS 000100 を定義します
#REG_UNONPOSIX 000200 を定義します
#REG_UUNSPEC 000400 を定義します
#REG_UUNPORT 001000 を定義します
#REG_ULOCALE 002000 を定義します
#REG_UEMPTYMATCH 004000 を定義します
#REG_UIMPOSSIBLE 010000 を定義します
#REG_USHORTEST 020000 を定義します
 int re_csize; /* sizeof(文字) */
 char *re_endp; /* 下位互換性のためのクルージ */
 Oid re_collat​​ion; /* LC_CTYPE の動作を定義する照合順序 */
 /* 残りは隠された内部への不透明なポインタです */
 char *re_guts; /* `char *' は `void *' よりも移植性が高い */
 char *re_fns;
} 正規表現t;

コンパイルされた正規表現を保存する

regmatch_t 構造体

/* 結果の報告 (後でさらにフィールドを取得する可能性があります) */
typedef構造体
{
 regoff_t rm_so; /* 部分文字列の開始 */
 regoff_t rm_eo; /* 部分文字列の終了 */
} regmatch_t;

typedef long regoff_t;

メンバー rm_so は、ターゲット文字列内の一致するテキスト文字列の開始位置を格納し、rm_eo は終了位置を格納します。通常、このような構造のグループを配列の形式で定義します。

いくつかの主な関数の宣言があります:

/*
 * エクスポートされた関数のプロトタイプ
 */
外部 int pg_regcomp(regex_t *, const pg_wchar *, size_t, int, Oid);
外部 int pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *, size_t, regmatch_t[], int);
外部 int pg_regprefix(regex_t *, pg_wchar **, size_t *);
外部 void pg_regfree(regex_t *);
extern size_t pg_regerror(int, const regex_t *, char *, size_t);
extern void pg_set_regex_collat​​ion(Oid 照合);

正規表現を処理するためによく使用される関数は、pg_regcomp()、pg_regexec()、pg_regfree()、および pg_regerror() です。

一般的な処理手順: 正規表現をコンパイルする pg_regcomp()、正規表現に一致する pg_regexec()、正規表現を解放する pg_regfree()。

pg_regerror(): regcomp または regexec の実行中にエラーが発生した場合、この関数を呼び出してエラー メッセージを含む文字列を返すことができます。

パラメータの説明

整数
pg_regcomp(regex_t *re,
   const chr *文字列, /* 正規表現文字列*/
   size_t len, /* 正規表現文字列の長さ*/
   intフラグ、
   OID照合

整数
pg_regexec(regex_t *re, /* regcomp関数でコンパイルされた正規表現*/
   const chr *文字列, /* 対象文字列*/
   size_t len, /* 対象文字列の長さ*/
   size_t search_start, /* 一致開始位置*/
   rm_detail_t *詳細, /* NULL */
   size_t nmatch、/* regmatch_t 構造体配列の長さ*/
   regmatch_t pmatch[], /* regmatch_t 型構造体配列、一致するテキスト文字列の位置情報を格納します*/
   int フラグ)

src/backend/utils/adt/regexp.c

/* 正規表現関数に関するすべてのオプション */
typedef 構造体 pg_re_flags
{
 int cflags; /* Spencer の正規表現コードのコンパイルフラグ */
 bool glob; /* グローバルに実行する(出現ごとに) */
} pg_re_flags;
/*
 * parse_re_flags - regexp_matches などのオプション引数を解析します
 *
 * フラグ --- 出力引数、必要なオプションが記入される
 * opts --- TEXTオブジェクト、またはデフォルトの場合はNULL
 *
 * これは、呼び出し元によって許可されたすべてのオプションを受け入れます。
 * 事後に拒否されてしまう事態を避けたい。
 */
静的ボイド
parse_re_flags(pg_re_flags *フラグ、テキスト *オプション)
{
 /* 正規表現のフレーバーは常にコンパイルフラグに組み込まれます */
 フラグ->cflags = REG_ADVANCED;
 flags->glob = false;

 if (オプション)
 {
 char *opt_p = VARDATA_ANY(opts);
 opt_len = VARSIZE_ANY_EXHDR(opts);
 整数 i;

 (i = 0; i < opt_len; i++) の場合
 {
  スイッチ (opt_p[i])
  {
  ケース 'g':
   フラグ->glob = true;
   壊す;
  case 'b': /* BRE (でもなぜ???) */
   フラグ->cflags &= ~(REG_ADVANCED | REG_EXTENDED | REG_QUOTE);
   壊す;
  case 'c': /* 大文字と小文字を区別します */
   フラグ->cflags &= ~REG_ICASE;
   壊す;
  case 'e': /* プレーンな ERE */
   フラグ->cflags |= REG_EXTENDED;
   フラグ->cflags &= ~(REG_ADVANCED | REG_QUOTE);
   壊す;
  case 'i': /* 大文字と小文字を区別しない */
   フラグ->cflags |= REG_ICASE;
   壊す;
  case 'm': /* n の Perloid 同義語 */
  case 'n': /* \n は ^ $ . [^ */ に影響します
   フラグ->cflags |= REG_NEWLINE;
   壊す;
  case 'p': /* ~Perl, \n は . [^ */ に影響します
   フラグ->cflags |= REG_NLSTOP;
   フラグ->cflags &= ~REG_NLANCH;
   壊す;
  case 'q': /* リテラル文字列 */
   フラグ->cflags |= REG_QUOTE;
   フラグ->cflags &= ~(REG_ADVANCED | REG_EXTENDED);
   壊す;
  case 's': /* 単一行、\n 通常 */
   フラグ->cflags &= ~REG_NEWLINE;
   壊す;
  case 't': /* 厳密な構文 */
   フラグ->cflags &= ~REG_EXPANDED;
   壊す;
  case 'w': /* 奇妙、\n は ^ $ のみに影響します */
   フラグ->cflags &= ~REG_NLSTOP;
   フラグ->cflags |= REG_NLANCH;
   壊す;
  case 'x': /* 拡張構文 */
   フラグ->cflags |= REG_EXPANDED;
   壊す;
  デフォルト:
   ereport(エラー、
    (エラーコード(ERRCODE_INVALID_PARAMETER_VALUE)、
    errmsg("無効な正規表現オプション: \"%c\"",
     opt_p[i])));
   壊す;
  }
 }
 }
}

オプション説明する
b残りの正規表現はBRです
c大文字と小文字を区別するマッチング(演算子タイプをオーバーライド)
e残りの正規表現はERE
大文字と小文字を区別しないマッチング(演算子タイプをオーバーライド)
メートルnの歴史的同義語
改行を感知するマッチング
p部分的な改行を区別する一致
q正規表現を、すべての通常の文字を含むリテラル (「引用符で囲まれた」) 文字列にリセットします。
s改行を区別しないマッチング(デフォルト)
t厳格な文法
改行を区別する(「奇妙な」)一致の一部を反転する
x拡張構文

上記は、PostgreSQL 正規表現のよく使用される関数の詳細な例です。ご質問がある場合は、メッセージを残すか、このサイトのコミュニティで議論してください。お読みいただきありがとうございます。お役に立てれば幸いです。このサイトをサポートしていただきありがとうございます。

以下もご興味があるかもしれません:
  • 解析を実装するためにPostgreSQLデータベースを書き込むSQLスクリプト関数
  • PostgreSQL データベースのウィンドウ関数の構文と使用法
  • PostgreSQL Node.jsでの関数計算メソッドの実装例
  • PostgreSQL におけるシーケンスと関連関数の使用法の詳細な分析
  • Postgresqlカスタム関数の詳細な説明

<<:  JavaScript カラービューア

>>:  FTP環境設定ソリューション(vsftpd)の詳細な説明

推薦する

Dockerfileを使用して独自のイメージを作成する方法

1. 空のディレクトリを作成する $ cd /home/xm6f/dev $ mkdir myapp...

MySQL 外部キー制約の無効化と有効化コマンド

MySQL 外部キー制約の無効化と有効化: MySQL 外部キー制約が有効になっているかどうかは、グ...

Vue のクロスドメイン問題の処理と解決策の概要

ネットワークリクエストを送信すると、次の保存情報が表示されます。おめでとうございます。ドメインを越え...

mysql+mycat、負荷分散、マスタースレーブレプリケーション、読み取り/書き込み分離操作に基づく安定した高可用性クラスタを構築します。

データベースのパフォーマンス最適化には、一般的にクラスタリングが採用されています。Oracle クラ...

src 属性と href 属性の違い

src と href には違いがあり、混同される可能性があります。 src は現在の要素を置き換える...

MySQL が大規模トランザクションを避けるべき理由とその解決方法

何が大問題ですか?長時間実行され、長時間コミットされないトランザクションは、大規模トランザクションと...

Vueフィルターとカスタム命令の使用

目次フィルター01.とは02. やり方(1)フィルターを定義する(2)使用方法(3)フィルタパラメー...

Windows で MySQL サービスを停止または削除できない問題の解決策

圧縮パッケージを解凍して Windows に MySQL をインストールしました。インストール方法は...

Vueは書籍ショッピングカートの機能を実現

この記事の例では、書籍ショッピングカート機能を実現するためのVueの具体的なコードを参考までに共有し...

MySQLインデックスを最適化する方法

1. MySQL のインデックスの使用方法インデックスは、特定の列の値を持つ行をすばやく見つけるため...

現在使用されている設定ファイル my.cnf を表示する mysql メソッド (推奨)

my.cnfは、MySQL の起動時に読み込まれる設定ファイルです。通常は MySQL インストー...

初心者向け入門チュートリアル: ドメイン名の解決とバインディング

では、ドメイン名を登録して仮想ホストを購入した後、IE でドメイン名を入力して Web サイトを開く...

ウェブページを開いて数秒後に他のページにリダイレクトする

これを実現するには、次のコードを追加するだけです。方法1: メタを使用する使用方法: <Met...

アイデア展開Tomcatサービス実装プロセス図

まずプロジェクトの成果物を構成するスタートアップ項目の設定 Tomcatサービスを作成する開始したい...

Vueはプルダウンを実装してさらに読み込む

Element-UI に慣れた開発者なら、無限スクロールの InfiniteScroll が使いにく...