'REG_NEWLINE' のときの '.' と '[^〜]' は改行 '^J' にはマッチしない。'REG_EXTENDED' のとき拡張正規表現、さもなくば基本正規表現。簡単なサンプルを以下に示す。
#include <regex.h> : int r, cflags = REG_EXTENDED, eflags = 0; regex_t reg; const char p[] = "^$"; const char b[] = "\n"; r = regcomp(®, p, cflags); const size_t n = 8; regmatch_t m[n]; r = regexec(®, b, n, m, eflags); : regfree(®); :
'\(', '\)' のグループ内の '\|' の論理和にバグあり('REG_EXTENDED' でないとき)。'[^\n]' が '^J#' の1文字目にマッチする('REG_NEWLINE' でも同様)。これは '\n' が改行コードを表すエスケープ文字としてではなく 'n' そのものであるからである。'[^^J]' とすれば意図した動作になる。'[^.]' が '^J#' の1文字目にマッチする('REG_NEWLINE' でも同様)。これは '.' が任意の文字ではなく '.' そのものであるからである。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記に対応。
簡単なサンプルは「POSIX regex.h in C」と同一で '-ltre -lintl -liconv' のリンクが必要。
'[^.]' が '^J#' の1文字目にマッチする('REG_NEWLINE' でも同様)。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記に対応。
簡単なサンプルは「POSIX regex.h in C」で当該ヘッダを '#include <pcreposix.h>' に変え、'-lpcreposix -lpcre' のリンク。
'[^\n]' が '^J#' の1文字目にマッチする('REG_NEWLINE' でないとき)。これは '\n' が改行コードを表すエスケープ文字としてではなく 'n' そのものであるからである。'[^^J]' とすれば意図した動作になる。'[^.]' が '^J#' の2文字目にマッチする('REG_NEWLINE' のとき)。これは '.' が任意の文字ではなく '.' そのものであるからである。'[^[:print:]]' が '^J#' にマッチしない('REG_NEWLINE' のとき)。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループには未対応。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記には未対応。'"<(.*)>.*</\\1>' のような後方参照が全滅('REG_EXTENDED' のとき)。簡単なサンプルは「POSIX regex.h in C」と同一。
'-E' でないときのグループに多々バグあり。'-E' のときの後方参照に少々バグあり。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記には未対応。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループには未対応。簡単なサンプルを以下に示す。
$ printf'\n'| grep'^$'
'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記には未対応。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループに対応。簡単なサンプルは「in FreeBSD sed」と同一。
'{n}', '{n,}', '{n,m}' のような繰返しはサポートされない。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループには未対応。簡単なサンプルを以下に示す。
printf'\n'| awk'/^$/'
'^' は文字列の途中にマッチ。'{n}', '{n,}', '{n,m}' のような繰返しをサポート。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループに対応。'gensub' の置換先のみサポート。簡単なサンプルは「in The One True Awk」と同一。
'.' は改行 '^J' にはマッチしない。'^J' にはマッチする。'{n}', '{n,}', '{n,m}' のような繰返しをサポート。'the ((Dark|Light|) *(Red|Green|Blue)) color' のような空のグループには未対応。簡単なサンプルを以下に示す。
printf'\n'| zsh -c'read b; [[ "$b" =~ '"'^$'"' ]] && echo "$b"'
zsh -c'printf "\n" | read b; [[ "$b" =~ '"'^$'"' ]] && echo "$b"'
'.' は '^J' にマッチしない('PCRE_DOTALL' でマッチする)。'REG_MULTILINE' に相当するフラグは 'PCRE_MULTILINE' である。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記に対応。簡単なサンプルを以下に示す。
#include <pcre.h> : int r, cflags = PCRE_DOTALL, erroffset, eflags = 0; pcre *reg; const char p[] = "^$"; const char b[] = "\n"; const char *error; reg = pcre_compile(p, cflags, &error, &erroffset, NULL); const size_t n = 8; int m[n]; r = pcre_exec(reg, NULL, b, strlen(b), 0, eflags, m, n); : pcre_free(reg); :
そして、'-lpcre' のリンクが必要。
'REG_MULTILINE' に相当するフラグは 'regex_constants::no_mod_m|regex_constants::no_mod_s' である。'regex_constants::extended' を加えると POSIX の拡張正規表現への互換性が高まる。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記に対応。簡単なサンプルを以下に示す。
#include <boost/regex.hpp> using namespace std; using namespace boost; : string p = "^$"; string b = "\n"; regex::flag_type cflags = regex_constants::normal; regex reg(p, cflags); smatch m; bool r = regex_search(b, m, reg); :
そして、'-lboost_regex' のリンクが必要。
'REG_MULTILINE' に相当するのが既定値で(正確には 'regex_constants::not_dot_newline' が必要)、その逆に相当するフラグが 'regex_constants::single_line' である。'/\\*.*?\\*/' のような最左最小(非貪欲)マッチ表記に対応。#include <boost/xpressive/xpressive.hpp> using namespace std; using namespace boost::xpressive; : string p = "^$"; string b = "\n"; sregex::flag_type cflags = regex_constants::single_line; sregex reg = sregex::compile(p, cflags); smatch m; bool r = regex_search(b, m, reg); :
そして、純粋なテンプレートライブラリなので、リンクは不要。