Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Negative Lookahead Equivalent in emacs

696 views
Skip to first unread message

luishenri...@gmail.com

unread,
May 9, 2017, 1:15:46 AM5/9/17
to
Hi,

I'm trying to write a regex that matches the last character of a sequence of non-whitespace characters '[^\n\r\t\f ]', or an empty line matching ^$.

Thus:
Hello World! --> "o" and "!" would be matched

In non-elisp regex languages I know the code for this is: \S(?!\S)
I know that \S is equivalent too [^ /n/r/t/f].
But I'm unsure of what the elisp equivalent (if any) of the negative lookahead (?!).

I saw on this forum a post "gnu.emacs.help › regex nirvana - near miss"
Where Drew Adams said: "Typically, what you want to do for this in Emacs Lisp is to combine
the use of a regexp for positive matching with other code that takes
care of the non-matching (negation) need. "

However, I'm not sure how to go about doing this.

Wasell

unread,
May 9, 2017, 5:54:29 AM5/9/17
to
On Mon, 8 May 2017 22:15:42 -0700 (PDT), in article <49e1dd7d-4be5-4b03-b9e2-
e26b15...@googlegroups.com>, luishenri...@gmail.com wrote:
>
> Hi,
>
> I'm trying to write a regex that matches the last character of a sequence of non-whitespace characters '[^\n\r\t\f ]', or an empty line matching ^$.
>
> Thus:
> Hello World! --> "o" and "!" would be matched
>
> In non-elisp regex languages I know the code for this is: \S(?!\S)
> I know that \S is equivalent too [^ /n/r/t/f].
> But I'm unsure of what the elisp equivalent (if any) of the negative lookahead (?!).
>
> I saw on this forum a post "gnu.emacs.help ? regex nirvana - near miss"
> Where Drew Adams said: "Typically, what you want to do for this in Emacs Lisp is to combine
> the use of a regexp for positive matching with other code that takes
> care of the non-matching (negation) need. "
>
> However, I'm not sure how to go about doing this.


If I'm not miss-understanding you completely, you want to match a non-
whitespace, followed either a whitespace or an end-of-line. That would be:

[^[:space:]]\(?:[[:space:]]\|$\)

Am I missing something?

Felix Dietrich

unread,
May 9, 2017, 6:03:29 AM5/9/17
to
luishenri...@gmail.com writes:

> I'm trying to write a regex that matches the last character of a
> sequence of non-whitespace characters '[^\n\r\t\f ]', or an empty line
> matching ^$.
>
> Thus:
> Hello World! --> "o" and "!" would be matched
>
> In non-elisp regex languages I know the code for this is: \S(?!\S)
> I know that \S is equivalent too [^ /n/r/t/f].

For your described behaviour something like the following might come
close to what you had in mind and does not require negative lookahead
support:

\\(?:[^\n\r\t\f ]*\\([^\n\r\t\f ]\\)\\)\\|^\n

The first shy group "\(?:\)" matches zero or more non-whitespace
characters and one more non-whitespace character (everything following
must be a whitespace character); the one non-whitespace character will
be available as the first group of the resultant match. Alternatively
"\|" it matches a line beginning with and (depending possibly on the
newline convention) therefore containing only a newline character,
i.e. an empty line.

Don't get confused by the plethora of backslashes: they require escaping
in an Emacs Lisp string to reach the regular expression functions as
proper backslashes; if they were not escaped they themself would escape
the following character.

> But I'm unsure of what the elisp equivalent (if any) of the negative
> lookahead (?!).

I do not know of the existence of an equivalent for the negative
lookahead feature of other regular expression engines in Emacs Lisp
regular expressions.

--
Felix Dietrich

luishenri...@gmail.com

unread,
May 9, 2017, 9:50:56 AM5/9/17
to
Thank you this worked out.

luishenri...@gmail.com

unread,
May 10, 2017, 10:24:00 AM5/10/17
to
No you're not missing anything. This one is a lot simpler :).
Thank you.

luishenri...@gmail.com

unread,
May 10, 2017, 11:51:28 AM5/10/17
to
On Tuesday, May 9, 2017 at 1:15:46 AM UTC-4, luishenri...@gmail.com wrote:
I edited the solution slightly so no new lines are included.

\[^[:space:]\n\]\\(?:\[[:space:]\]\\|$\\)

There are a lot of backslashes because I used regex-builder to test it.
0 new messages