Main Content

パターン表現の作成

R2020b 以降

パターンは、テキストの検索と変更に役立つツールです。正規表現と同様に、パターンはテキスト照合のルールを定義します。パターンを containsmatchesextract などのテキスト検索関数と共に使用して、これらの関数が作用するテキストの部分を指定できます。数式の作成と同様な方法で、パターン関数、演算子およびリテラル テキストを使用して、パターン表現を作成できます。パターン表現には制限がないため、パターンが非常に複雑になることがあります。段階的にパターンを作成し、maskedPatternnamedPattern などの関数を使用すると、複雑なパターンを整理できます。

シンプルなパターンの作成

最もシンプルなパターンは、単一のパターン関数から作成されます。たとえば、lettersPattern はすべての文字と一致します。異なるタイプの文字、およびテキストの他の特徴を照合する多くのパターン関数があります。これらの関数のリストは、patternのリファレンス ページにあります。

txt = "abc123def";
pat = lettersPattern;
extract(txt,pat)
ans = 2x1 string
    "abc"
    "def"

パターンを他のパターンおよびリテラル テキストと組み合わせるには、plus(+) 演算子を使用します。この演算子は、パターン表現に定義された順序でパターンとテキストを連結します。連結されたパターンは、同じ順序のテキストにのみ一致します。この例では、4 文字の文字列がテキストの末尾になければならないため、"YYYY/MM/DD" は一致しません。

txt = "Dates can be expressed as MM/DD/YYYY, DD/MM/YYYY, or YYYY/MM/DD";
pat = lettersPattern(2) + "/" + lettersPattern(2) + "/" + lettersPattern(4);
extract(txt,pat)
ans = 2x1 string
    "MM/DD/YYYY"
    "DD/MM/YYYY"

or(|) 演算子を使用したパターンは、指定された 2 つのパターンのうち 1 つのみがテキストの一部と一致する必要があることを指定します。いずれのパターンも一致しない場合、パターン表現は照合に失敗します。

txt = "123abc";
pat = lettersPattern|digitsPattern;
extract(txt,pat)
ans = 2x1 string
    "123"
    "abc"

一部のパターン関数はパターンを入力として受け入れ、何らかの形でパターンを変更します。たとえば、optionalPattern は可能であれば指定されたパターン一致に含まれますが、照合が成功するためにそのパターンは必須ではありません。

txt = ["123abc" "abc"];
pat = optionalPattern(digitsPattern) + lettersPattern;
extract(txt,pat)
ans = 1x2 string
    "123abc"    "abc"

境界パターン

境界パターンは特殊なタイプのパターンで、文字と一致するのではなく、指定された文字のタイプと他の文字の間にある境界、またはそのテキストの先頭または末尾と一致します。たとえば、digitBoundary は数字と数字以外の文字との間にある境界、および数字とテキストの先頭または末尾との間にある境界と一致します。数字自体とは一致しません。境界パターンは、split のような関数の区切り記号として便利です。

txt = "123abc";
pat = digitBoundary;
split(txt,pat)
ans = 3x1 string
    ""
    "123"
    "abc"

境界パターンは、not(~) 演算子を使用して否定できるため、パターンの中でも特殊です。この方法で否定すると、境界パターンは前述の要件を満たさない文字の前または後と一致します。たとえば、~digitBoundary は次の間の境界と一致します。

  • 両方が数字

  • 両方が数字以外の文字

  • 数字以外の文字と、テキストの先頭または末尾

replace を使用して、~digitBoundary で一致した位置を文字 "|" でマークします。

txt = "123abc";
pat = ~digitBoundary;
replace(txt,pat,"|")
ans = 
"1|2|3a|b|c|"

複雑なパターンの段階的な作成

問題を解くためにシンプルなパターンでは不十分で、より複雑なパターンが必要になる場合があります。パターン表現が長くなるにつれて、一致するものがわかりにくくなることがあります。複雑なパターンの作成を簡略化する 1 つの方法は、パターンの各部を個別に作成してから、各部を組み合わせて単一のパターン表現にすることです。

たとえば、電子メール アドレスは local_part@domain.TLD の形式を使用しています。3 つの識別子、local_part、domain および TLD はそれぞれ、数字、文字およびアンダースコア文字の組み合わせでなければなりません。パターン全体を作成するには、識別子のパターンの定義から始めます。1 つの文字、1 つの数字または 1 つのアンダースコア文字と一致するパターンを作成します。

identCharacters = alphanumericsPattern(1) | "_";

次に、asManyOfPattern を使用して、1 つ以上の連続する identCharacters のインスタンスと一致させます。

identifier = asManyOfPattern(identCharacters,1);

次に、複数の識別子を含む電子メール アドレスと一致するパターンを作成します。

emailPattern = identifier + "@" + identifier + "." + identifier;

次の例の電子メール アドレスにどのぐらいよく一致するかを確認することで、このパターンをテストします。

exampleEmails = ["janedoe@mathworks.com" 
    "abe.lincoln@whitehouse.gov"
    "alberteinstein@physics.university.edu"];
matches(exampleEmails,emailPattern)
ans = 3x1 logical array

   1
   0
   0

すべての電子メール アドレスが有効であるにもかかわらず、このパターンは例の電子メール アドレスのいくつかと一致しません。local_part と domain の両方は、ピリオドで区切られた一連の識別子で構成できます。identifier のパターンを使用して、一連の識別子に一致可能なパターンを作成します。asManyOfPattern は、可能な限り多く、指定されたパターンの同時出現と一致しますが、一致しない場合でもパターンの残りが良好に一致可能です。

identifierSeries = asManyOfPattern(identifier + ".") + identifier;

このパターンを使用して、例の電子メール アドレスのすべてと一致する新しい emailPattern を作成します。

emailPattern = identifierSeries + "@" + identifierSeries + "." + identifier;
matches(exampleEmails,emailPattern)
ans = 3x1 logical array

   1
   1
   1

パターン表示の整理

複雑なパターンは読みづらく解釈しにくいことがあり、特にパターンを共有したユーザーがパターンの構造に不慣れな場合は困難です。たとえば、表示された emailPattern は、長くて読みづらいものです。

emailPattern
emailPattern = pattern
  Matching:

    asManyOfPattern(asManyOfPattern(alphanumericsPattern(1) | "_",1) + ".") + asManyOfPattern(alphanumericsPattern(1) | "_",1) + "@" + asManyOfPattern(asManyOfPattern(alphanumericsPattern(1) | "_",1) + ".") + asManyOfPattern(alphanumericsPattern(1) | "_",1) + "." + asManyOfPattern(alphanumericsPattern(1) | "_",1)

表示に関する問題の一部は、identifier パターンの繰り返しが多いことです。このパターンのユーザーにとってパターンの正確な細部が重要でない場合は、maskedPattern を使用して identifier パターンの表示を隠すことができます。この関数は、identifier の表示をマスクして変数名 "identifier" を代わりに表示する新しいパターンを作成します。あるいは、表示する別の名前を指定できます。この方法でマスクされるパターンの詳細には、表示されたパターン内の [Show all details] をクリックすることでアクセスできます。

identifier = maskedPattern(identifier);
identifierSeries = asManyOfPattern(identifier + ".") + identifier
identifierSeries = pattern
  Matching:

    asManyOfPattern(identifier + ".") + identifier

  Use details to show more information

関数 namedPattern を使用して、パターンをさらに整理できます。namedPattern は、他のパターンと組み合わせたときにパターンの表示方法が変化する名前付きパターンとして、パターンを指定します。電子メール アドレスにはいくつかの重要な部分 local_part@domain.TLD があり、これらのそれぞれに固有の一致ルールがあります。各セクション用の名前付きパターンを作成します。

localPart = namedPattern(identifierSeries,"local_part");

名前付きパターンを入れ子にして、パターンの各部をさらに記述できます。名前付きパターンを入れ子にするには、名前付きパターンを使用してパターンを作成してから、そのパターンを名前付きパターンとして指定します。たとえば、Domain.TLD はドメイン、サブドメインおよび最上位ドメイン (TLD) に分けることができます。domain.TLD の各部の名前付きパターンを作成します。

subdomain = namedPattern(identifierSeries,"subdomain");
domainName = namedPattern(identifier,"domainName");
tld = namedPattern(identifier,"TLD");

単一の名前付きパターン domain の下に、domain の構成要素の名前付きパターンを入れ子にします。

domain = optionalPattern(subdomain + ".") + ...
            domainName + "." + ...
            tld;
domain = namedPattern(domain);

パターンをすべて組み合わせて単一の名前付きパターン emailPattern にします。emailPattern の表示では、個々の名前付きパターンとそれが一致するもの、および入れ子にされた名前付きパターンに関する情報を確認できます。

emailPattern = localPart + "@" + domain
emailPattern = pattern
  Matching:

    local_part + "@" + domain

  Using named patterns:

    local_part  : asManyOfPattern(identifier + ".") + identifier
    domain      : optionalPattern(subdomain + ".") + domainName + "." + TLD
      subdomain : asManyOfPattern(identifier + ".") + identifier
      domainName: identifier
      TLD       : identifier

  Use details to show more information

パターンへのドットインデックスにより、名前付きパターンおよび入れ子にされた名前付きパターンにアクセスできます。たとえば、入れ子にされた名前付きパターン subdomain にアクセスするには、emailPattern から domain にドットインデックスを付けてから、再び subdomain にドットインデックスを付けます。

emailPattern.domain.subdomain
ans = pattern
  Matching:

    asManyOfPattern(identifier + ".") + identifier

  Use details to show more information

ドットの代入を使用すると、パターン表現の残りを書き直すことなく名前付きパターンを変更できます。

emailPattern.domain = "mathworks.com"
emailPattern = pattern
  Matching:

    local_part + "@" + domain

  Using named patterns:

    local_part: asManyOfPattern(identifier + ".") + identifier
    domain    : "mathworks.com"

  Use details to show more information

Copyright 2020 The MathWorks, Inc.

参考

| | | | |

関連するトピック