3

I want to search using regexp to capture plain text. I want to capture passages that begin with opening quotation marks and end at the end of the paragraph, and even though the quote continues onto a new paragraph, I want to capture only the first part (In the following: The dog wagged it's tail.) Note that there are no closing quotation marks at the end of the paragraph because the quote itself continues.

Bob said: ``The dog wagged it's tail.

``But that's not the end of my story,'' said Bob, continuing.

This is the result I hope to achieve.

I say I want to "exclude repeated characters" because I don't want to capture to the end of the paragraph when the quote closes, i.e., when there are closing quotes, thus:

''

In other words, I want to accept single apostrophes but not double apostrophes.

Edit: Now that I have this solution, provided by phils below, here's the complete result: Hi-lock formatting.

And once the file is loaded, enable hi-lock: M-x hi-lock-mode

Also: M-x customize-group RET hi-lock-faces

  • For me the regexp in the following re-search works: (re-search-forward "``\\(?:\n?[^`\n]+\\)+") – Tobias Mar 24 at 14:59
  • Many thanks here. @Tobias, I can't get this to work. It may be trouble with "\n", so I have tried it C-q RET, also \\n, \r\n etc. And I think [^`\n] should probably be [^'\n]. But neither work for me. Thanks anyway--it looks very clever. I did get something to work: "``[^']+.[^']+.[^']+.[^']$" , but it's not an acceptable solution, partly because it seems to be a massive amount of computation---a reasonable passage of text takes minutes to process. Still hoping. Cheers. – seeker Mar 25 at 0:56
  • I've edited the title because I can now see the basic problem is that I want to capture from ` ` (two back ticks) to the end of the line, but only when there are not two consecutive quote marks (i.e., closing quote is ' ' ). – seeker Mar 26 at 7:05
  • Note that the solution to your problem is not as simple as you think it is. You are dealing with a multi-line fontification here. One kind of multiline fontification bases on an Elisp functions instead of the regexp. I think that is also a simpler solution to your problem. – Tobias Mar 26 at 10:59
3

Based on the screenshot, you are only interested in quotes spanning multiple lines. Here's a patten for that:

"\\(``\\(?:[^'\n]\\|'[^'\n]\\)*'?\\)\n\\(?:.\\|\n\\)*?''"

Or in rx syntax:

(rx (seq (group "``" (zero-or-more (or (not (in "\n'"))
                                       (seq "'" (not (in "\n'")))))
                (zero-or-one "'"))
         "\n" (minimal-match (zero-or-more anything)) "''"))

Note that we handle single ' characters with this:

"\\(?:[^'\n]\\|'[^'\n]\\)*'?

Which says match zero-or-more repetitions of:

  1. Any single character which is neither ' nor a newline.
  2. A ' character followed by any single character which is neither ' nor a newline.

Followed optionally by a single ' immediately before the newline.


Group 1 is the part to highlight. e.g. with hi-lock-mode:

Hi-lock: (("\\(``\\(?:[^'\n]\\|'[^'\n]\\)*'?\\)\n\\(?:.\\|\n\\)*?''"
           (1 (quote hi-green-b) prepend)))
  • n.b. You can omit the seq wrapper in rx; but it's needed for rx-to-string (and hence in re-builder), so it can be handy to include it regardless. – phils Mar 26 at 21:45
  • That may answer the question but the real problem of the OP lies deeper. – Tobias Mar 27 at 9:15
  • I'm grateful for your efforts, but please read the question. 1. "...I want to capture only the first part (The dog wagged it's tail.)" 2. "The following regexp doesn't work because it captures both lines, and I only want the first line with this particular highlight." 3. From the quoted text: "...only when there are not two consecutive quote marks...." 4. From the title: "...exclude repeated characters" – seeker Mar 27 at 18:16
  • Thank you very much for this phils. This is tremendously helpful. I have a lot of text (novels), and checking it all is very slow. This this makes it ten thousand times quicker, and it's completely reliable; I've been testing it. Could you please make this an answer so I can accept it. Thank you phils and @Tobias for your patience and persistence. – seeker Mar 28 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.