[ruby-list:50533] 正規表現のキャプチャで悩む
From:
俊(とし) <toshio.otaguro@...>
Date:
2017-06-04 02:11:37 UTC
List:
ruby-list #50533
どうにも理解できないのでここでお尋ねします.
文字列をある規則で解釈しようと思います.行頭に空白以外の単語構成文字を置き,同一の文字が続く限りキャプチャします.空白を置かずに異なる文字が現れたら,そこから行末までをキャプチャします.同一文字の並びの後に空白が来たらエラーとします.正規表現では,
/\A((\w)\2+)([[^\2]&&\w].*)\Z/
でよいと思うのですが,
p /\A((\w)\2+)([[^\2]&&\w].*)\Z/.match("aaabcd")
#=> #<MatchData "aaabcd" 1:"aaa" 2:"a" 3:"bcd">
p /\A((\w)\2+)([[^\2]&&\w].*)\Z/.match("aaa bcd")
#=> #<MatchData "aaa bcd" 1:"aa" 2:"a" 3:"a bcd">
となって,2番目の例がエラーとならずにマッチしてしまいます.$3 が "a bcd" となるのが不可解です.それではと思い他の書き方を試してみると,
p /\A((\w)\k<2>+)([[^\k<2>]&&\w].*)\Z/.match("aaa bcd")
#=> #<MatchData "aaa bcd" 1:"aa" 2:"a" 3:"a bcd">
p
/\A(?<head>(?<alpha>\w)\k<alpha>+)(?<tail>[[^\k<alpha>]&&\w].*)\Z/.match("aaa
bcd")
#=> nil
となり,最後の例だけがマッチせずに正しい挙動であることがわかります.
使用した Ruby は Windows 10 (64bit) 上の Rubyinstaller2 (64bit) 2.4.1 です.
私の考え方のどこがまずいのか,ご教示いただけないでしょうか?
--
俊(とし)