Gauche:regexp

Gauche:regexp


\w は _ にマッチしないのですね

satoru Perl や Ruby と違って Gauche の \w は _ にマッチしないのですね。 勘違いしていてちょっとはまりました。


^ は文字列の先頭ではなく行頭にマッチして欲しいな

satoru ^ は文字列の先頭ではなく、行頭にマッチするという仕様のほうが便利だと思うんですが、いかがでしょう。

  gosh> (rxmatch #/^foo/ "foo")
  #<<regmatch> 0x81a8a80>
  gosh> (rxmatch #/^foo/ "abc\nfoo")
  #f

Ruby では ^ は行頭にマッチします。 文字列の先頭にマッチさせるには \A を使います。

  % irb                  
  >> /^foo/ === "foo"
  => 0
  >> /^foo/ === "abc\nfoo"
  => 4
  >> /\Afoo/ === "foo"
  => 0
  >> /\Afoo/ === "abc\nfoo"
  => nil

Perl では /m を指定すると ^ が行頭にマッチするようになります。 この辺は処理系によってまちまちでややこしいすね。

Shiro: いくつかの理由で、Gaucheのregexpでは「行」という概念を意図的に落してあります。


大文字小文字の区別をしないマッチング

satoru 正規表現のマッチングで大文字小文字の区別をしないようにする方法はありますでしょうか? Perl や Ruby っぽく #/abc/i のように書けるとうれしいです。

  % irb
  >> /abc/i.match("AbC")
  => #<MatchData:0x401e8034>
  (define (rxstring-expand-ci str)
    (regexp-replace-all 
     #/([^[\\]*)(\\.|\[^?]?[^]]+\])?/ str
     (lambda (m) (string-append 
                  (regexp-replace-all 
                   #/([a-zA-Z])/
                   (rxmatch-substring m 1)
                   (lambda (mm) (string-append 
                                 "["
                                 (string-downcase (rxmatch-substring mm 1))
                                 (string-upcase (rxmatch-substring mm 1))
                                 "]")))
                  (or (rxmatch-substring m 2) "")))))
  (define (test str)
    (format #t "~s => ~s\n" str (rxstring-expand-ci str)))
  (test "aBc")
  (test "aBc[a-z]dEf")
  (test "aBc[]a-z]dEf")
  (test "aBc[^]a-z]dEf")
  (test "aBc[.]a-z]dEf")
  (test "aB\\[\\nc[.\\]a-z]dEf")

実行結果:

  "aBc" => "[aA][bB][cC]"
  "aBc[a-z]dEf" => "[aA][bB][cC][a-z][dD][eE][fF]"
  "aBc[]a-z]dEf" => "[aA][bB][cC][]a-z][dD][eE][fF]"
  "aBc[^]a-z]dEf" => "[aA][bB][cC][^]a-z][dD][eE][fF]"
  "aBc[.]a-z]dEf" => "[aA][bB][cC][.][aA]-[zZ]][dD][eE][fF]"
  "aB\\[\\nc[.\\]a-z]dEf" => "[aA][bB]\\[\\n[cC][.\\][aA]-[zZ]][dD][eE][fF]"
  
     (cond ((rxmatch #/ab[a-z]ef/i "ABCEF") => rxmatch-substring) (else #f))
        ==> "ABCEF"
     (rxmatch #/abc/ string) ≡ (#/abc/ string)
     (rxmatch-substring m 1) ≡ (m 1)
     (rxmatch-after m)       ≡ (m 'after)
     (map (lambda (i) (rxmatch-substring m i)) '(1 2 3) ≡ (map m '(1 2 3))

正規表現オブジェクトからパターンの元の文字列を知しりたい

satoru 正規表現オブジェクトから、パターンの元の文字列を知ることはできないでしょうか? regexp->string があるとうれしいです。

  % gosh
  gosh> #/foo/
  #<<regexp> 0x8193340>

ちなみに、Ruby では Regexp#inspect で知ることができます。

  % irb 
  >> /foo/
  => /foo/
  >> /foo/.inspect
  => "/foo/"
  >> /foo/.to_s
  => "#<Regexp:0x401e8ca0>"

あと、regexp? がなかったので次のコードでごまかしました。

  (define (regexp? obj)
    (is-a? obj <regexp>))

参考

Tag: 正規表現

More ...