Clojure regular expression


 * (Python) Regular Expression Howto http://docs.python.org/dev/howto/regex.html

= Regular expression =


 * 正規表現でsplitする.
 * 正規表現にマッチした文字列、およびその前後の文字列を取り出す.

Python
p = re.compile('ab*', re.IGNORECASE)

Java
compile時に以下のようなflagsを指定できる.

CASE_INSENSITIVE MULTILINE DOTALL UNICODE_CASE CANON_EQ UNIX_LINES LITERAL COMMENTS

Clojure
正規表現のリテラルは#"pattern"です. patternはエスケープする必要がありません.

リテラルで書くとjava.util.regex.Patternをコンパイルしたものを得られます.

すなわち と (java.util.regex.Pattern/compile "\\d+") は同義です. http://rd.clojure-users.org/entry/view/14001
 * 1) "\d+"

●フラグ一覧

埋め込みフラグと、Patternクラスでの定義.

(?i)	CASE_INSENSITIVE	大文字小文字区別しない (?m)	MULTILINE	複数行モード (?s)	DOTALL	DOTALL モード (?u)	UNICODE_CASE	大文字と小文字を区別しない. ワイド文字列版. (?d)	UNIX_LINES	Unixの改行のみマッチ（\rは改行文字とみなさない) (?x)	COMMENTS	Unixラインモードを有効にする なし	CANON_EQ	正規等価を有効にする なし	LITERAL	パターンのリテラル構文解析を有効にする

(re-seq #"(?m)^..." "abcd\nefg\nhijk") ;;=> ("abc" "efg" "hij")
 * 複数行モード

(re-seq #"(?m)^..." "abcd efg hijk") ;;=> ("abc" "efg" "hij")
 * Clojureでは文字列内に普通に改行も入れることが出来ます.

(re-find #"(?s)......" "abcd\nefg\nhijk") ;;=> "abcd\ne" http://d.hatena.ne.jp/minazoko/20100531/1275309344
 * DOTAILモード. メタ文字 "." が行末にマッチ

Python
Pythonにおいては、完全一致をMatchingとよび、部分一致をSearchingと呼んでいる. >>> p = re.compile('(a(b)c)d') >>> m = p.match('abcd') >>> m.group(0) 'abcd' >>> m.group(1) 'abc' >>> m.group(2) 'b' >>> m.group(2,1,2) ('b', 'abc', 'b') >>> m.groups ('abc', 'b')

Clojure
http://rd.clojure-users.org/entry/view/14001

Java
Javaでは先頭一致はlookingAtメソッドである.

部分一致
部分一致の場合、さらに以下のバリエーションがある.
 * 部分一致した一番最初の文字列の位置あるいは文字列自身を取り出す
 * （部分一致したn番目の文字列の位置あるいは文字列自身を取り出す. ）
 * 部分一致した文字列全部をリストとして返す

Java
Javaでは部分一致はfindメソッドである.

部分一致した文字列全部をリストとして返すには、while文の中などでm.findを繰り返し呼び出す.

Clojure
http://nakkaya.com/2009/10/25/regular-expressions-in-clojure/

サブパターンに一致した文字列を取り出す
正規表現中でカッコを使うとサブパターンが定義できる. これにマッチした文字列を取り出す.

Java
Matcherのgroup(int i)を使う.

Clojure
http://nakkaya.com/2009/10/25/regular-expressions-in-clojure/

Python
m.start, m.endを使えば、マッチした部分文字列の先頭位置、末尾位置を取得できる. これを使って部分文字列を取り出せばよい.

>>> p1 = re.compile("cde") >>> str = "abcdefghij" >>> m = p1.search(str) >>> m.end 5 >>> str[:m.start] 'ab' >>> str[m.start:m.end] 'cde' >>> str[m.end:] 'fghij' >>>

Lookahead assertion
>>> p1 = re.compile("a(?=b)") >>> p1.match("abcd").group 'a' >>> p2 = re.compile("a(?!b)") >>> p2.match("abcd").group Traceback (most recent call last): File " ", line 1, in AttributeError: 'NoneType' object has no attribute 'group'


 * (?=...) Positive lookahead assertion.
 * (?!...) Negative lookahead assertion.

= Substitution =

Python
>>> p = re.compile( '(blue|white|red)') >>> p.sub( 'colour', 'blue socks and red shoes') 'colour socks and colour shoes' >>> p.sub( 'colour', 'blue socks and red shoes', count=1) 'colour socks and red shoes'

結局、次のperlコードは $text = 'the cat sat on the mat'; $text =~ s/cat/slug/; 次のように書き換えることができる. text = 'the cat sat on the mat' text = re.sub(r'cat','slug', text)

Clojure
clojure.contrib.str-utils.re-gsub

re-gsubはマッチした文字列をすべて置換

http://d.hatena.ne.jp/minazoko/20100531/1275309344

Clojure
clojure.contrib.str-utils.re-sub

re-subはマッチした最初の文字列のみ置換

http://d.hatena.ne.jp/minazoko/20100531/1275309344

= split =