From: Suraj Kurapati Date: 2011-11-09T18:38:14+09:00 Subject: [ruby-core:40878] [ruby-trunk - Feature #5588] add negation flag (v) to Regexp Issue #5588 has been updated by Suraj Kurapati. You are correct, Tanaka. I have been exploring the regexp implementation to understand why and I learned that the negate flag must be compiled as an opcode (similar to multiline and ignorecase) into the re_pattern_buffer->p string. My current approach is to compile (?v:...) into two opcodes (OP_BEGIN_NEGATE and OP_END_NEGATE) with normal compilation of the ... stuff inside. Later, when match_at() in regexec.c:1254 is processing the compiled regexp and encounters OP_END_NEGATE, it will perform the negation: If we consumed > 0 input characters since OP_BEGIN_NEGATE, then we have successfully matched the ... stuff inside the original (?v:...) regexp. So we need to stop further processing by returning ONIG_MISMATCH. Otherwise, we did not consume any input characters since OP_BEGIN_NEGATE, so we continue processing by returning ONIG_NORMAL. This effectively treats the (?v:...) as a zero-length regexp, which always matches of course. That's my plan for now. Any comments? Thanks for your consideration. ---------------------------------------- Feature #5588: add negation flag (v) to Regexp http://redmine.ruby-lang.org/issues/5588 Author: Suraj Kurapati Status: Open Priority: Normal Assignee: Category: Target version: Please add a negation flag (v) to regexps which inverts them: "ruby" =~ /perl/v #=> true (turn on negation) "ruby" !~ /perl/v #=> false (turn on negation) "ruby" =~ /(?v:perl)/ #=> true (turn on negation) "ruby" !~ /(?v:perl)/ #=> false (turn on negation) "ruby" =~ /(?-v:perl)/ #=> false (turn off negation) "ruby" !~ /(?-v:perl)/ #=> true (turn off negation) The flag name "v" comes from the ex(1) command of the same name. This has beneficial applications where it is sometimes difficult to construct what you want to match but much easier to construct what you *do not* want to match. Having this negation built in the regexp itself would remove the need for us to change our Ruby code to process a regexp in a different way. For example, suppose that you are passing a regexp to the `--name` command-line option of MiniTest. This regexp tells MiniTest to only run those tests whose names match. If Ruby had a negation flag on its regexps, then it would be suddenly trivial to make MiniTest skip certain tests by negating the regexp we pass in. In this manner, we get a beneficial feature without ever changing our Ruby code (the codebase of MiniTest in this example). :-) Thanks for your consideration. -- http://redmine.ruby-lang.org