# Regex in Ruby question

**URL:** <https://rubytalk.org/t/regex-in-ruby-question/44703>\
**Category:** ruby-talk\
**Created:** [22 February 2008 17:31 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703 "2008-02-22T17:31:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![J\_Cooper](https://avatars.discourse-cdn.com/v4/letter/j/3e96dc/32.png) [@J\_Cooper](https://rubytalk.org/u/J_Cooper)\
**Post date:** [22 February 2008 17:31 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/1 "2008-02-22T17:31:33Z")

</div>

Another newbie question:

I've just started learning about regex "officially" (reading the  
O'reilly book) and was trying out some of the examples (porting them to  
Ruby from Perl). From what I can tell, Ruby's regex engine doesn't  
support "lookbehind", and as I had only a smattering of knowledge about  
regex before and no prior experience with lookaround, I was curious if  
this was significant.

i.e. is there any problem that can't be solved without lookbehind?

(Note that I am not facing such a problem; I'm just curious if  
lookbehind is just an optional feature that makes certain problems  
easier, as opposed to being an essential thing.)

Thanks!

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![ThoML](https://avatars.discourse-cdn.com/v4/letter/t/d78d45/32.png) [@ThoML](https://rubytalk.org/u/ThoML)\
**Post date:** [22 February 2008 18:04 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/2 "2008-02-22T18:04:57Z")

</div>

> From what I can tell, Ruby's regex engine doesn't  
> support "lookbehind"

Ruby 1.9 has look-behind:

&nbsp;&nbsp;(?\<=subexp) look-behind  
&nbsp;&nbsp;(?\<!subexp) negative look-behind

With ruby 1.8, you can install Oniguruma.

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![Sebastian\_Hungereck1](https://avatars.discourse-cdn.com/v4/letter/s/3ab097/32.png) [@Sebastian\_Hungereck1](https://rubytalk.org/u/Sebastian_Hungereck1)\
**Post date:** [22 February 2008 19:09 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/3 "2008-02-22T19:09:56Z")

</div>

J. Cooper wrote:

> i.e. is there any problem that can't be solved without lookbehind?

Yes, there are. For example: you want to match any occurence of "bar" except  
if it is preceeded by "foo". I.e. you'd want to match "blabar" or "oofbar",  
but not "foobar". You can't do that without negative lookbehind.  
It might be interesting to note though, that any such problem could also not  
be solved by a regular grammar, so "regular" expressions that need lookbehind  
aren't, as such, regular anymore.

HTH,  
Sebastian

> **···**
>
> --  
> Jabber: sepp2k@jabber.org  
> ICQ: 205544826

---

<div class="post-metadata">

**Author:** ![ThoML](https://avatars.discourse-cdn.com/v4/letter/t/d78d45/32.png) [@ThoML](https://rubytalk.org/u/ThoML)\
**Post date:** [22 February 2008 19:39 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/4 "2008-02-22T19:39:57Z")

</div>

> Yes, there are. For example: you want to match any occurence of "bar" except  
> if it is preceeded by "foo". I.e. you'd want to match "blabar" or "oofbar",  
> but not "foobar".

I think it's important to state that the look-behind matches with zero  
width, i.e. the match isn't included in the match.

If it's okay to include the prefix in the match (e.g., in a gsub, the  
prefix could then be referenced as a group), this could also be  
achieved without lookbehind:

require 'strscan'  
# 0 1 2 3  
# 0123456789012345678901234567890123  
s = StringScanner.new('blabar oofbar foobar ofobar offbar')  
# ^ ^ ^ ^  
until s.eos?  
&nbsp;&nbsp;&nbsp;&nbsp;m = s.scan\_until(/([^o]|[^o]o|[^f]oo)(bar)/)  
&nbsp;&nbsp;&nbsp;&nbsp;p s.pos  
end

# =\>  
6  
13  
27  
34

pos 20 is missing.

There are of course situations when this isn't possible.

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![Mark\_Bush](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Mark\_Bush](https://rubytalk.org/u/Mark_Bush)\
**Post date:** [22 February 2008 20:12 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/5 "2008-02-22T20:12:48Z")

</div>

ThoML wrote:

> There are of course situations when this isn't possible.

require 'strscan'  
# 0 1 2 3  
# 0123456789012345678901234567890123456789  
s = StringScanner.new('obar blabar oofbar foobar ofobar offbar')  
# ^ ^ ^ ^  
until s.eos?  
&nbsp;&nbsp;&nbsp;&nbsp;m = s.scan\_until(/([^o]|[^o]o|[^f]oo)(bar)/)  
&nbsp;&nbsp;&nbsp;&nbsp;p s.pos  
end

# =\>  
11  
18  
32  
39

☹  
However, with:  
&nbsp;&nbsp;&nbsp;&nbsp;m = s.scan\_until(/(([^o]|^)|([^o]|^)o|([^f]|^)oo)(bar)/)

=\>  
4  
11  
18  
32  
39

🙂

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![ThoML](https://avatars.discourse-cdn.com/v4/letter/t/d78d45/32.png) [@ThoML](https://rubytalk.org/u/ThoML)\
**Post date:** [22 February 2008 20:30 UTC](https://rubytalk.org/t/regex-in-ruby-question/44703/6 "2008-02-22T20:30:01Z")

</div>

> However, with:  
> &nbsp;&nbsp;&nbsp;&nbsp;m = s.scan\_until(/(([^o]|^)|([^o]|^)o|([^f]|^)oo)(bar)/)

Oh well. It's probably a good thing we have look-behind now. 🙂

Regards,  
Thomas.
