tags:

views:

45

answers:

2

Hey I'm trying to use a regex to count the number of quotes in a string that are not preceded by a backslash.. for example the following string:

  • "\"Some text
  • "\"Some \"text

The code I have was previously using String#count('"') obviously this is not good enough

When I count the quotes on both these examples I need the result only to be 1

I have been searching here for similar questions and ive tried using lookbehinds but cannot get them to work in ruby.

I have tried the following regexs on Rubular from this previous question

  • /[^\\]"/
  • ^"((?<!\\)[^"]+)"
  • ^"([^"]|(?<!\)\\")"

None of them give me the results im after

Maybe a regex is not the way to do that. Maybe a programatic approach is the solution

Thanks --Rob

+3  A: 

How about string.count('"') - string.count("\\"")?

FRotthowe
well i never thought of doing that, it works. I think that will do.:)
Rob
+1 for thinking straight and simple.
Amarghosh
+2  A: 
result = subject.scan(
    /(?:        # match either
     ^         # start-of-string\/line
    |          # or
     \G        # the position where the previous match ended
    |          # or
     [^\\]     # one non-backslash character
    )          # then
    (\\\\)*    # match an even number of backslashes (0 is even, too)
    "          # match a quote/x)

gives you an array of all quote characters (possibly with a preceding non-quote character) except unescaped ones.

The \G anchor is needed to match successive quotes, and the (\\\\)* makes sure that backslashes are only counted as escaping characters if they occur in odd numbers before the quote (to take Amarghosh's correct caveat into account).

Tim Pietzcker
+1 for \G. That's the bit I've been missing in my attempt.
sepp2k
it returns an array of nils however the number of nils is the number of quotes so its perfect, thanks!`'"\"foo\"bar"'.scan(/(?:^|\G|[^\\])(\\\\)*"/x).size => 2`
Rob