> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 抽出ルールのサンプル

> NLP 抽出ルールの実用例 — 最後のエンティティインスタンス、金額の単語表記と数字表記、セグメント検出、当事者のグループ化、日付と時刻のペアリング。

このセクションでは、コードエディターで作成した抽出ルールのサンプルをいくつか紹介します。コードエディターはグラフィカルユーザーインターフェースよりも柔軟で、使用する構文の詳細は [Syntax](/ja/vantage/documentation/advanced-designer/activities/nlp-extraction-rules/code-syntax/syntax) セクションを参照してください。

<div id="finding-the-last-instance-of-a-named-entity">
  ## 名前付きエンティティの最後の出現箇所を見つける
</div>

この例では、抽出ルールを使用して賃貸借契約書における借主の組織名を見つけます。この名称は他のすべての組織名の後に現れ、GUI の設定では抽出できません。GUI では **Instances > First** しか選択できないためです。ただし、抽出ルールを使用して、角括弧で囲まれた "Tenant" という語の直前に現れる組織名を検索できます。

まず補助的な検索要素としてキーワード "Tenant" を見つけます。次に、そのキーワードの前に現れる組織名を探します。この例では、間に入るトークンが 2 つ（開き括弧と引用符）あるため、安全余裕を見込んで距離を 3 トークンに制限します。お使いのドキュメントでキーワードと組織名の間により多くのトークンが介在する場合は、この数値を適宜増やしてください。

<div id="rule-for-extracting-the-last-organization-instance">
  ### 直近の組織インスタンスを抽出するためのルール
</div>

```
// 1つのインスタンスのみを検索
~TenantName
// キーワード「Tenant」の前に出現する組織名を検索
// キーワードとの間隔は3トークン以内
// 間にあるトークンに別の組織名を含めないこと
[ t: @NEROrganization ]+ [ ~@NEROrganization ~@kw_Tenant ]{0,3} [ @kw_Tenant ]
=>
TenantName( t );
```

<div id="example">
  ### 例
</div>

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_sampleslastinstance.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=388c6b8b78d27784f2c1b9f19dfed147" alt="賃貸借契約書の抜粋。テナントの組織名が TenantName 検索要素に抽出された例" width="1017" height="82" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_sampleslastinstance.png" />
</Frame>

<div id="extract-an-amount-of-money-stated-both-in-words-and-as-a-numeral">
  ## 金額が文字表記と数字表記の両方で記載されている場合の抽出
</div>

この例では、正規表現を用いた抽出ルールにより、まず文字で記載され、その後に丸括弧内で数字で示された金額を抽出します。例:

Two Thousand One Hundred Forty-Seven Dollars and Sixty Cents (\$2,147.60)

Two Thousand One Hundred Forty-Seven Dollars and Sixty Cents (in numbers: \$2,147.60)

<div id="rule-for-extracting-an-amount-of-money">
  ### 合計金額を抽出するためのルール
</div>

```
// 変数 a は、数字ではない Money 名前付きエンティティを受け取り、
// まだ Money 検索要素の他のインスタンスに割り当てられていないもの
[ a: @NERMoney( same ) ~@Money ~/\d+/ ]+
[ br: '(' ]
// 疑問符は、「in numbers」という単語がオプションであることを意味します
// ^ と $ 記号は、文字列全体が正規表現に一致する必要があることを意味します
// i オプションは、大文字と小文字を区別しない一致を意味します
( [ e1: /^in$/i ] [ e2: /^numbers$/i ] [ e3: ':' ]? )?
// 変数 b は、括弧内に配置された Money 名前付きエンティティを受け取ります
[ b: @NERMoney( same ) ~@Money ]+
=>
Money( a + br + e1 + e2 + e3 + b );
```

<div id="example">
  ### 例
</div>

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_samplesmoneywordsdigits.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=3e5e6ddce3c026db047f5f1db664221d" alt="単語による表記と括弧付きの数字表記を組み合わせた単一の値として合計金額が抽出された例" style={{ width:"45%" }} width="826" height="297" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_samplesmoneywordsdigits.png" />
</Frame>

<div id="finding-segments-by-means-of-keywords">
  ## キーワードによるセグメントの検索
</div>

この例では、Segmentation アクティビティで確実に検出できないセグメントを見つけるために抽出ルールを使用します。ルールは、セグメントの開始または終了となるキーワードを探し、その間のテキストを抽出します。

ドキュメントには、すべて大文字で書かれた番号付きの第2レベル見出しがあると仮定します。例: 1.1 PREMISES、2.3 LIABILITY AND INDEMNITY など。また、第1レベルの見出しは、検索要素 "kw\_Heading1" にすでに抽出済みであるとします（簡潔のため、該当する抽出ルールは省略します）。

まず、ドキュメントの各段落の先頭にあるキーワードを探し、それらを検索要素 "kw\_Heading2." に抽出します。次に、連続する2つのキーワードの間のテキストを検索要素 "Segment." に格納します。

Advanced Designer の現行バージョンでは、コードエディターは固有表現の検出に使用される検索要素でのみ利用可能です。回避策として、コードで見出しやセグメントのようなテキストを抽出するには、サポートされている固有表現（例: **Organization**）の検索要素を作成し、その要素のコードエディターにルールのコードを入力してください。

<div id="rule-for-extracting-second-level-headings-into-the-kw_heading2-search-element">
  ### 第2レベル見出しを kw\_Heading2 検索要素に抽出するためのルール
</div>

```
// 最大5単語の全て大文字で構成された番号付き第2レベル見出しを検索
// 見出し番号は1つのトークンとして検出される可能性があります: 1.1
[ t1: /\d{1,2}\.\d{1,2}/ ] [ t2: <all_letters_capitalized> ]{1,5}
=>
kw_Heading2( t1 + t2 );
// 見出し番号は3つの別々のトークンとして検出される可能性があります: 1、ドット、1
[ t1: /\d{1,2}/ ] [ t2: '.' ] [ t3: /\d{1,2}/ ] [ t4: <all_letters_capitalized> ]{1,5}
=>
kw_Heading2( t1 + t2 + t3 + t4 );
```

<div id="rule-for-extracting-the-segment-into-the-segment-search-element">
  ### セグメントを「Segment search」要素に抽出するためのルール
</div>

```
// 連続する2つのセクション見出し間のテキストセグメントを検索
// 第1レベルの見出しも除外
[ @kw_Heading2 ] [ interval: ~@kw_Heading2 ~@kw_Heading1 ]+
=>
Root.Segment( interval );
```

<div id="example">
  ### 例
</div>

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_samplessegments.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=5a13cbb13cd4c69f1cbc7ab152d07273" alt="連続する第2レベル見出しの間のドキュメントのテキストが Segment 検索要素に抽出される例" width="990" height="212" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_samplessegments.png" />
</Frame>

この例では、「3.1 FIRSTLY」と「3.2 SECONDLY」という語が `kw_Heading2` 検索要素に抽出され、その後、連続する2つの `kw_Heading2` 検索要素の間にあるテキストが、`Segment` 検索要素のインスタンスとして抽出されます。

<div id="grouping-information-about-each-entity">
  ## 各エンティティに関する情報のグループ化
</div>

この例では、合意書の各当事者に関する詳細が正しくグループ化されるよう、抽出ルールを使用します（つまり、各当事者の氏名と住所が1つのグループインスタンスにまとまり、複数のインスタンスに分割されたり、相手方の情報と混在したりしないようにします）。

考え方は、常に先頭に現れる当事者の識別情報を見つけることです。これは、合意書の作成方法によって複数のやり方が考えられます。

この例では、各組織の名称が常に先頭にあり、その後に住所と合意書における役割が続くと仮定します。したがって、次のようにします。

1. 組織名を検出し、見つかった各名称に対して `Party_Group` のグループ検索要素の新しいインスタンスを作成し、その子検索要素「`Organization_Name`」に値を設定します。
2. 各組織名のインスタンスから、例えば20トークン以内の範囲にある住所と役割を探し、その組織名の親である `Party_Group` のインスタンスにアクセスして、そのインスタンス内の子検索要素「`Address`」および「`Role`」に値を設定します。

データの検索対象は、Segmentation アクティビティで検出され、Extraction Rules アクティビティに Input field「Parties\_Segment」として渡されたセグメント内に限定されます。

<div id="rule-for-extracting-the-organization_name-search-element">
  ### Organization\_Name 検索要素の抽出ルール
</div>

```
// 組織名を検索し、各組織に対して新しいグループインスタンスを作成
[ org: @NEROrganization( same ) ~@Party_Group.Organization_Name @Parties_Segment ]+
=>
// Party_Groupの新しいインスタンスを作成し、Organization_Nameに入力
Party_Group.Organization_Name( org );
```

<div id="rule-for-extracting-the-address-search-element">
  ### Address 検索要素の抽出ルール
</div>

```
// 次に、組織名から20トークン以内に位置する住所を検索します
// この住所はまだParty_Group内のいずれの組織にも割り当てられていないものです
// 
[ org: @Party_Group.Organization_Name( same ) ]+
[ ~@NERAddress ]{0,20}
[ t: @NERAddress( same ) ~@Party_Group.Address @Parties_Segment ]+
=>
// 組織名の親であるParty_Groupのインスタンスにアクセスし
// そのAddressの子要素を入力します
parent( obj( org )).Address( t );
```

<div id="rule-for-extracting-the-role-search-element">
  ### 役割検索要素抽出のルール
</div>

```
// ロールについても同様に繰り返す
// ロールを検索するには、キーワードを使用する
[ org: @Party_Group.Organization_Name( same ) ]+
[ ~("Tenant" | "Landlord" | "Broker") ]{0,20}
[ t: "Tenant" | "Landlord" | "Broker" ~@Party_Group.Role @Parties_Segment ]+
=>
parent( obj( org )).Role( t );
```

<div id="example">
  ### 例
</div>

検索要素は次のように抽出されます。

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_samplesgroupdata.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=c4b5148ffe843f15615417bd5c837997" alt="各当事者の組織名、住所、役割が正しくグループ化されて抽出された Party_Group インスタンス" width="1129" height="193" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_samplesgroupdata.png" />
</Frame>

データ フォームでは、各会社の名前、住所、役割も、それぞれ別のグループ インスタンスの下にまとめられていることがわかります。

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_samplesgroupdatafields.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=e3f34a0f4c94ee1f0a2fce081a30b79e" alt="各会社の名前、住所、役割がそれぞれ別の Party_Group インスタンス番号の下に表示されたデータ フォーム" width="1003" height="157" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_samplesgroupdatafields.png" />
</Frame>

各組織の詳細は、角括弧内のインスタンス番号が示すように、まとめてグループ化されています。

<div id="finding-the-date-and-time-together">
  ## 日付と時刻をまとめて検出する
</div>

この例では、抽出ルールを使って時刻と日付の組み合わせを検出します。

まず、**Value from Regular Expression** 型の検索要素「Time」を使用します（使用する正規表現は `[1]?\d:\d{2}\s+(([ap]\.m\.)|([AP]M))?`）。次に、その近傍にある **Date** という名前のエンティティを探します。最後に、検出したトークン列を連結し、結果を「TimeAndDate」という名前の検索要素に割り当てます。

<div id="rule-for-extracting-date-and-time-combined">
  ### 日付と時刻の併記抽出ルール
</div>

```
// 正規表現検索要素のValueを使用して時刻を検索
// @NERDateを使用して時刻に近いDate名前付きエンティティを検索
[ time: @Time ~@TimeAndDate ]+ [ t: ~@NERDate ]{0,3} [ date: @NERDate( same ) ]+
=>
// 値を結合して1つのfieldに書き込む
// 連続したトークンシーケンスのみ結合可能なため、補助トークンも追加
TimeAndDate( time + t + date );
```

<div id="example">
  ### 例
</div>

<Frame>
  <img src="https://mintcdn.com/abbyy/Bmjdl5TjCaidPxKi/images/vantage/advanced-designer/ad_extractionrulesnlp_samplestimeanddate.png?fit=max&auto=format&n=Bmjdl5TjCaidPxKi&q=85&s=d8549ae06800dee774477d0951e95cb1" alt="連結された時刻と日付の固有表現を単一の TimeAndDate 検索要素に抽出した例" style={{ width:"45%" }} width="1035" height="228" data-path="images/vantage/advanced-designer/ad_extractionrulesnlp_samplestimeanddate.png" />
</Frame>
