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

推薦する

Alibaba Cloud ホストが IP を使用して Web サイトにアクセスできない問題の解決策 (セキュリティ グループ ルールを構成することで解決)

Alibaba Cloud ホストを購入したばかりで、その速度を試すのが待ちきれませんでした。しか...

nginx をコンパイルしてインストールした後、スムーズに nginx をアップグレードする方法

nginx をコンパイルしてインストールし、一定期間使用した後、現在のバージョンに脆弱性があることや...

CSSにスティッキー効果を追加する方法

前面に書かれたfilter:blur と filter:contrast がこのような素晴らしい化学...

bash を使って日付をカウントダウンする方法

重要なイベントまであと何日あるか知りたいですか? Linux bash と date コマンドが役に...

Mysqlトランザクション操作の失敗を解決する方法

Mysqlトランザクション操作の失敗を解決する方法トランザクションの原子性: トランザクションは、デ...

MySQL で自動インクリメントシーケンスを実装するためのサンプルコード

1. シーケンステーブルを作成する テーブル `sequence` を作成します ( `name` ...

JavaScript における一般的な配列操作

目次1. 連結() 2. 結合() 3. プッシュ() 5. シフト() 6. シフト解除() 7....

Dockerのローカルイメージ作成方法の分析

コンテナと呼ばれるものは、実際には親イメージに基づいて読み取りおよび書き込み可能なファイル階層を作成...

Vue で $attrs と $listeners を使用するチュートリアル

目次導入例要約する導入$属性すべての親コンポーネントのプロパティを継承します (props を通じて...

MYSQL ログとバックアップおよび復元の問題の詳細な説明

この記事では、参考までにMYSQLログとバックアップとリストアについて紹介します。具体的な内容は以下...

Viteの新しい体験の詳細な説明

Vite とは何ですか? (フロントエンドの新しいおもちゃです) Vite は、ネイティブ ES モ...

HTML テーブルインライン形式の詳細な説明

インライン形式<colgroup>...</colgroup>属性名 属性値...

SpringBoot アプリケーションの Docker デプロイメントの実装手順

目次序文DockerファイルDockerfile とは何ですか? Dockerfile 構文Spri...

TypeScript における列挙型の理解と応用シナリオ

目次1. 何ですか2. 使用数値列挙文字列列挙異種列挙自然3. 応用シナリオ要約する1. 何ですか列...

Python3.6-MySql 挿入ファイルパス、バックスラッシュをなくす解決策

以下のように表示されます。上記のように、置き換えるだけです。 Python3.6-MySql でファ...