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)の詳細な説明

推薦する

Vue での bimface の使用に関する詳細

目次1. Vue スキャフォールディングをインストールする2. プロジェクトを作成する3.1 プロジ...

MySQL ステートメントにおける IN と Exists の比較分析

背景最近、SQL 文を書くときに、IN と Exists のどちらを選択するか迷ったので、両方の方法...

MySQLデータベースを操作するためのコマンドラインツールmycliの簡単な紹介

GitHub にはあらゆる種類の魔法のツールがあります。今日、私はデータベースを操作するためのコマン...

モバイル端末のジャンプ問題を解決する(CSS遷移、ターゲット疑似クラス)

序文モバイル端末に触れたばかりの友人の多くは、クリックジャンプルーティング、特にVueルーティングを...

中国における中国語ドメイン名の人気は新たなクライマックスを迎えた

<br />外交部などの中央政府機関、各レベルの地方政府、その他の国家機関や部門が率先し...

Reactを使用して画像認識アプリを実装する方法

まずは効果の写真をお見せしましょう。 個人的には効果は問題ないと思います。アプリが写真を学習する時間...

MYSQL ストアドプロシージャと関数の簡単な記述

ストアドプロシージャとは簡単に言えば、これは強力で、JAVA 言語のメソッドに似た比較的複雑な論理関...

Dreamweaver8を使用してウェブサイトのファイルをチェックして整理する方法

Dreamweaver8 を使用して独自の Web サイトを作成する目的は何ですか?インターネットに...

MySQL でのインデックスの追加と削除に関連する操作

目次1. インデックスの役割2. インデックスの作成と削除(1)ALTER TABLE文を使用して、...

Ubuntuにmysql5.7.10を手動でインストールする

このチュートリアルでは、UbuntuにMySQL 5.7.10を手動でインストールする手順を参考まで...

Element PlusはAffixを実装します

目次1. コンポーネントの紹介2. ソースコード分析2.1 テンプレート2.2 スクリプト2.3 実...

MySQL 8.0.22 のダウンロード、インストール、設定方法のグラフィックチュートリアル

参考までにMySQL 8.0.22をダウンロードしてインストールしてください。具体的な内容は次のとお...

TypeScript 学習ノート: 型の絞り込み

目次序文型推論真理値の絞り込み平等の縮小演算子の絞り込みインスタンスの絞り込み狭まりの本質ユニオン型...

Nginx サーバーの https 設定方法の例

Linux: Linux バージョン 3.10.0-123.9.3.el7.x86_64 ngin...

WeChatアプレットでSVGアイコンを使用する方法

SVG は、さまざまな利点があるため、近年広く使用されています。残念ながら、WeChat ミニプログ...