> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 正規表現ツリー辞書 のレイアウト

> パターンベースのルックアップ用の正規表現ツリー辞書 を設定します。

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            Not supported in ClickHouse Cloud
        </div>;
};

<div id="overview">
  ## 概要
</div>

`regexp_tree` Dictionary では、階層的な正規表現パターンに基づいてキーを値にマッピングできます。
完全一致によるキー照合ではなく、パターン一致のルックアップ (たとえば、正規表現パターンとの照合によって user agent 文字列のような文字列を分類するケース) 向けに最適化されています。

<Frame>
  <iframe src="https://www.youtube.com/embed/ESlAhUJMoz8?si=sY2OVm-zcuxlDRaX" title="ClickHouse の regex tree Dictionary 入門" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

<div id="use-regular-expression-tree-dictionary-in-clickhouse-open-source">
  ## YAMLRegExpTree ソースを使用した正規表現ツリー辞書
</div>

ClickHouse Open Sourceでは、正規表現ツリーを含む YAML ファイルへのパスを指定した [`YAMLRegExpTree`](/ja/reference/statements/create/dictionary/sources/yamlregexptree) ソースを使用して、正規表現ツリー辞書を定義します。

```sql title="Query" theme={null}
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
...
```

Dictionary ソース [`YAMLRegExpTree`](/ja/reference/statements/create/dictionary/sources/yamlregexptree) は、正規表現ツリーの構造を表します。たとえば、次のとおりです。

```yaml theme={null}
- regexp: 'Linux/(\d+[\.\d]*).+tlinux'
  name: 'TencentOS'
  version: '\1'

- regexp: '\d+/tclwebkit(?:\d+[\.\d]*)'
  name: 'Android'
  versions:
    - regexp: '33/tclwebkit'
      version: '13'
    - regexp: '3[12]/tclwebkit'
      version: '12'
    - regexp: '30/tclwebkit'
      version: '11'
    - regexp: '29/tclwebkit'
      version: '10'
```

このconfigは、正規表現ツリーノードのリストで構成されています。各ノードは次の構造を持ちます。

* **regexp**: ノードの正規表現。
* **属性**: ユーザー定義のDictionary 属性のリスト。この例では、`name` と `version` の2つの属性があります。最初のノードでは両方の属性を定義しています。2番目のノードでは `name` 属性のみを定義しています。`version` 属性は、2番目のノードの子ノードによって提供されます。
  * 属性の値には、マッチした正規表現のcapture groupを参照する**後方参照**を含めることができます。この例では、最初のノードの `version` 属性の値は、正規表現内のcapture group `(\d+[\.\d]*)` への後方参照 `\1` で構成されています。後方参照の番号は1から9までで、`$1` または `\1` (1番の場合) のように記述します。後方参照は、クエリの実行時にマッチしたcapture groupで置き換えられます。
* **子ノード**: regexp tree nodeの子ノードのリストです。各子ノードは、それぞれ独自の属性と、必要に応じて子ノードを持ちます。文字列のマッチングは深さ優先で行われます。文字列がregexp nodeにマッチした場合、dictionaryはその文字列がそのノードの子ノードにもマッチするかどうかを確認します。その場合、最も深い階層でマッチしたノードの属性が割り当てられます。子ノードの属性は、同じ名前の親ノードの属性を上書きします。YAMLファイル内の子ノードの名前は任意で、たとえば上記の例では `versions` です。

Regexp tree dictionariesでは、`dictGet`、`dictGetOrDefault`、`dictGetAll` の各関数を使ったアクセスのみが可能です。例:

```sql title="Query" theme={null}
SELECT dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024');
```

```text title="Response" theme={null}
┌─dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024')─┐
│ ('Android','12')                                                │
└─────────────────────────────────────────────────────────────────┘
```

この場合、まず最上位レイヤーの2 番目のノードで正規表現 `\d+/tclwebkit(?:\d+[\.\d]*)` に一致します。
その後、Dictionary は子ノードの探索を続け、その文字列が `3[12]/tclwebkit` にも一致することを見つけます。
その結果、属性 `name` の値は `Android` (第1レイヤーで定義) となり、属性 `version` の値は `12` (子ノードで定義) となります。

高度な YAML 設定ファイルを使うことで、regexp tree dictionaries をユーザーエージェント文字列のパーサーとして使用できます。
ClickHouse は [uap-core](https://github.com/ua-parser/uap-core) をサポートしており、その使用方法は functional test [02504\_regexp\_dictionary\_ua\_parser](https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/02504_regexp_dictionary_ua_parser.sh) で確認できます。

<div id="collecting-attribute-values">
  ### 属性値の収集
</div>

一致した複数の正規表現から、末端ノードの値だけでなく複数の値を返したい場合があります。そのような場合は、専用の [`dictGetAll`](/ja/reference/functions/regular-functions/ext-dict-functions#dictGetAll) 関数を使用できます。ノードが型 `T` の attribute 値を持つ場合、`dictGetAll` は 0 個以上の値を含む `Array(T)` を返します。

デフォルトでは、キーごとに返される一致数に上限はありません。`dictGetAll` には、省略可能な第 4 引数として上限を指定できます。配列には *トポロジカル順序* で値が格納されます。つまり、子ノードは親ノードより前に配置され、兄弟ノードはソース内の順序に従います。

例:

```sql theme={null}
CREATE DICTIONARY regexp_dict
(
    regexp String,
    tag String,
    topological_index Int64,
    captured Nullable(String),
    parent String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
LIFETIME(0)
```

```yaml theme={null}
# /var/lib/clickhouse/user_files/regexp_tree.yaml
- regexp: 'clickhouse\.com'
  tag: 'ClickHouse'
  topological_index: 1
  paths:
    - regexp: 'clickhouse\.com/docs(.*)'
      tag: 'ClickHouse Documentation'
      topological_index: 0
      captured: '\1'
      parent: 'ClickHouse'

- regexp: '/docs(/|$)'
  tag: 'Documentation'
  topological_index: 2

- regexp: 'github.com'
  tag: 'GitHub'
  topological_index: 3
  captured: 'NULL'
```

```sql title="Query" theme={null}
CREATE TABLE urls (url String) ENGINE=MergeTree ORDER BY url;
INSERT INTO urls VALUES ('clickhouse.com'), ('clickhouse.com/docs/en'), ('github.com/clickhouse/tree/master/docs');
SELECT url, dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2) FROM urls;
```

```text title="Response" theme={null}
┌─url────────────────────────────────────┬─dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2)─┐
│ clickhouse.com                         │ (['ClickHouse'],[1],[],[])                                                            │
│ clickhouse.com/docs/en                 │ (['ClickHouse Documentation','ClickHouse'],[0,1],['/en'],['ClickHouse'])              │
│ github.com/clickhouse/tree/master/docs │ (['Documentation','GitHub'],[2,3],[NULL],[])                                          │
└────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘
```

<div id="matching-modes">
  ### マッチングモード
</div>

パターンマッチングの動作は、特定の Dictionary 設定によって変更できます。

* `regexp_dict_flag_case_insensitive`: 大文字と小文字を区別しないマッチングを使用します (デフォルトは `false`) 。個々の式では `(?i)` と `(?-i)` を使って上書きできます。
* `regexp_dict_flag_dotall`: `.` が改行文字にも一致するようにします (デフォルトは `false`) 。

<div id="use-regular-expression-tree-dictionary-in-clickhouse-cloud">
  ## ClickHouse Cloudで正規表現ツリー辞書を使用する
</div>

[`YAMLRegExpTree`](/ja/reference/statements/create/dictionary/sources/yamlregexptree) ソースはClickHouse Open Sourceでは使用できますが、ClickHouse Cloudでは使用できません。
ClickHouse Cloudで正規表現ツリー辞書を使用するには、まずClickHouse Open SourceでYAMLファイルから正規表現ツリー辞書をローカルに作成し、次に `dictionary` テーブル関数と [INTO OUTFILE](/ja/reference/statements/select/into-outfile) 句を使って、このDictionaryをCSVファイルにダンプします。

```sql theme={null}
SELECT * FROM dictionary(regexp_dict) INTO OUTFILE('regexp_dict.csv')
```

CSVファイルの内容は次のとおりです:

```text theme={null}
1,0,"Linux/(\d+[\.\d]*).+tlinux","['version','name']","['\\1','TencentOS']"
2,0,"(\d+)/tclwebkit(\d+[\.\d]*)","['comment','version','name']","['test $1 and $2','$1','Android']"
3,2,"33/tclwebkit","['version']","['13']"
4,2,"3[12]/tclwebkit","['version']","['12']"
5,2,"3[12]/tclwebkit","['version']","['11']"
6,2,"3[12]/tclwebkit","['version']","['10']"
```

ダンプファイルのスキーマは次のとおりです。

* `id UInt64`: RegexpTree ノードの ID。
* `parent_id UInt64`: ノードの親の ID。
* `regexp String`: 正規表現の文字列。
* `keys Array(String)`: ユーザー定義属性の名前。
* `values Array(String)`: ユーザー定義属性の値。

ClickHouse Cloud で Dictionary を作成するには、まず次のテーブル構造で `regexp_dictionary_source_table` テーブルを作成します。

```sql theme={null}
CREATE TABLE regexp_dictionary_source_table
(
    id UInt64,
    parent_id UInt64,
    regexp String,
    keys   Array(String),
    values Array(String)
) ENGINE=Memory;
```

次に、ローカルのCSVを以下のように更新します

```bash theme={null}
clickhouse client \
    --host MY_HOST \
    --secure \
    --password MY_PASSWORD \
    --query "
    INSERT INTO regexp_dictionary_source_table
    SELECT * FROM input ('id UInt64, parent_id UInt64, regexp String, keys Array(String), values Array(String)')
    FORMAT CSV" < regexp_dict.csv
```

詳しくは、[ローカルファイルの挿入](/ja/integrations/connectors/data-ingestion/insert-local-files)を参照してください。ソーステーブルを初期化した後、テーブルソースから RegexpTree を作成できます。

```sql theme={null}
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
PRIMARY KEY(regexp)
SOURCE(CLICKHOUSE(TABLE 'regexp_dictionary_source_table'))
LIFETIME(0)
LAYOUT(regexp_tree);
```
