Regular Expressions

M

Mmcolli00 Mom

Hi everyone.

Just a question about regualar expression in Ruby. Is there a way to
check in each line of a document for always beginning with "23430000"
and somewhere on that same line another string 'CodeRed'?

line1: 23430000 @#$#$3455000CodeRed 24AAWERE 740000000

This is what I have so far when I import each textdata from another
file.


textdata.should =~ /23430000/ |CodeRed/

...the pipe was supposed to determine if CodeRed exists somewhere after
the identity code 23430000. However, it doesn't work like this. Also for
my code I am not using OR logic with it.
 
Y

Yaser Sulaiman

[Note: parts of this message were removed to make it a legal post.]

I'm not sure if this is what you are asking for, but /23430000.*CodeRed/
will match a line that contains '23430000', followed by zero or more
characters, and then 'CodeRed'.

try in IRB:

irb(main):001:0> line1 = '23430000 @#$#$3455000CodeRed 24AAWERE 740000000'
=> "23430000 @\#$\#$3455000CodeRed 24AAWERE 740000000"
irb(main):002:0> line1 =~ /23430000.*CodeRed/
=> 0
irb(main):003:0> line2 = '23430000 @#$#$3455000CodeGreen 24AAWERE 740000000'
=> "23430000 @\#$\#$3455000CodeGreen 24AAWERE 740000000"
irb(main):004:0> line2 =~ /23430000.*CodeRed/
=> nil

Regards,
Yaser Sulaiman
 
J

James Gray

Hi everyone.
Hello.

Just a question about regualar expression in Ruby. Is there a way to
check in each line of a document for always beginning with "23430000"
and somewhere on that same line another string 'CodeRed'?
Sure.

line1: 23430000 @#$#$3455000CodeRed 24AAWERE 740000000

This is what I have so far when I import each textdata from another
file.


textdata.should =~ /23430000/ |CodeRed/

textdata.should =~ /\A23430000.*CodeRed/

My changes are simple:

* \A is a regex atom the only matches at the beginning of the input.
I used this to make sure 23430000 is at the beginning of the line and
not later.
* .* matches zero or more of pretty much anything. Newlines are the
only character excluded. Thus this allows anything to appear between
the number and CodeRed.

Now the regex above really just checks one line. If you want to check
all lines, you'll want something like:

textdata.each do |line|
line.should =~ /\A23430000.*CodeRed/
end

Hope that helps.

James Edward Gray II
 
K

Kyle Schmitt

Hi everyone.

Just a question about regualar expression in Ruby. Is there a way to
check in each line of a document for always beginning with "23430000"
and somewhere on that same line another string 'CodeRed'?

line1: 23430000 @#$#$3455000CodeRed 24AAWERE 740000000

This is what I have so far when I import each textdata from another
file.


textdata.should =~ /23430000/ |CodeRed/

...the pipe was supposed to determine if CodeRed exists somewhere after
the identity code 23430000. However, it doesn't work like this. Also for
my code I am not using OR logic with it.

I just wanted to mention another way of combining regexes that may
help you stay sane: union.

#You write each regex nice and simple like..
startswith=/~23430000/
codered=/CodeRed/

#Then combine them to a complex one
combined_regex=Regexp.union(startswith,codered)

When you've got to build up some large regular expressions, this can
be a godsend, especially when revisiting code you haven't looked at in
awhile.

--Kyle
 
K

Kyle Schmitt

I just wanted to mention another way of combining regexes that may
help you stay sane: union.

#You write each regex nice and simple like..
startswith=/~23430000/
codered=/CodeRed/

#Then combine them to a complex one
combined_regex=Regexp.union(startswith,codered)

When you've got to build up some large regular expressions, this can
be a godsend, especially when revisiting code you haven't looked at in
awhile.

--Kyle

Scratch that, not thinking clearly! This is to match startswith OR
codered, not necessarily both.

Still, I maintain that this is a way of staying sane with complex regexes :)
 
Y

Yaser Sulaiman

[Note: parts of this message were removed to make it a legal post.]

Still, I maintain that this is a way of staying sane with complex regexes :)
It certainly looks helpful. I didn't know about it before. Thanks for
sharing :)

Regards,
Yaser
 
M

Mmcolli00 Mom

Kyle said:
Scratch that, not thinking clearly! This is to match startswith OR
codered, not necessarily both.

Still, I maintain that this is a way of staying sane with complex
regexes :)

Alright. thanks for the tip. I was just thinking...what is the
regexpression for starts with anyway? I don't know..I figured maybe I
could use union with the starts with expression and then just grab that
value.
 
J

Joe Wölfel

Scratch that, not thinking clearly! This is to match startswith OR
codered, not necessarily both.

Still, I maintain that this is a way of staying sane with complex =20
regexes :)

Interesting that there is a union function but no intersection function.=
 
R

Rob Biedenharn

Interesting that there is a union function but no intersection =20
function.


How would you even define a regexp (re) that matched only when both of =20=

two other regexps (re1, re2) matched?

class Regexp
def self.intersection(re1,re2)
union(compile(/(?>#{re1}).*#{re2}/),
compile(/(?>#{re2}).*#{re1}/))
end
end

re =3D Regexp.intersection(re1,re2)

What would you expect the value to be? And while Regexp.union is well-=20=

behaved for multiple arguments, the expansion for more arguments in =20
the intersection gets ugly fast.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
S

Sebastian Hungerecker

Joe said:
Interesting that there is a union function but no intersection function [=
for=20
regexen].

Well, the union of two regexen /foo/ and /bar/ is simply /foo|bar/, so the=
=20
union method is rather easily implemented. An intersection method would be=
=20
somewhat more complex. Of course that's not really a reason not to implemen=
t=20
it, but it might be the reason why it's not implemented yet.

HTH,
Sebastian
=2D-=20
Jabber: (e-mail address removed)
ICQ: 205544826
 
J

Joe Wölfel

How would you even define a regexp (re) that matched only when both =20=
of two other regexps (re1, re2) matched?

class Regexp
def self.intersection(re1,re2)
union(compile(/(?>#{re1}).*#{re2}/),
compile(/(?>#{re2}).*#{re1}/))
end
end

re =3D Regexp.intersection(re1,re2)

What would you expect the value to be? And while Regexp.union is =20
well-behaved for multiple arguments, the expansion for more =20
arguments in the intersection gets ugly fast.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)

Not sure I understand. Are you arguing that an intersection cannot =20
exist as a regular expression or merely that it is hard?=20
=20=
 
R

Rob Biedenharn

Not sure I understand. Are you arguing that an intersection cannot =20=
exist as a regular expression or merely that it is hard?

That it becomes combinatorially hard to construct such a regexp in =20
general. If I want a regexp that matches the intersection of /a/ and /=20=

b/ and /c/ (i.e., contains each of 'a', 'b', and 'c'), I have to =20
account for all the permutations (manually):
/a.*b.*c/
/a.*c.*b/
/b.*a.*c/
/b.*c.*a/
/c.*a.*b/
/c.*b.*a/

Or combined as: /(?:a.*(?:b.*c)|(?:c.*b))|(?:b.*(?:a.*c)|(?:c.*a))|=20
(?:c.*(?:b.*a)|(?:a.*b))/

That's nasty and so much worse than the union /[abc]/ or /a|b|c/ even =20=

for this relatively simple case. It would be better to do this at the =20=

application level if you can't guarantee order:

[/a/, /b/, /c/].all? {|re| mystring =3D~ re }

And then the value of the match can be whatever the application wants =20=

to track.

-Rob=
 
K

Ken Bloom

How would you even define a regexp (re) that matched only when both of
two other regexps (re1, re2) matched?

class Regexp
def self.intersection(re1,re2)
union(compile(/(?>#{re1}).*#{re2}/),
compile(/(?>#{re2}).*#{re1}/))
end
end

re = Regexp.intersection(re1,re2)

What would you expect the value to be? And while Regexp.union is well-
behaved for multiple arguments, the expansion for more arguments in the
intersection gets ugly fast.

It's very well defined if you're talking about an underlying
deterministic finite automaton. That's an simple proof that is usually
assigned as an exercise for the student in a computer science theory
course.

If re1 compiles to a DFA dfa1=(S1,s1,A1,f1)
where S1 is the set of all states, s1 is the start state, A1 is the set
of accepting states, and f1(s'1,input) is the transition function
and re2 compiles to a DFA dfa2=(S2,s2,A2,f2)

Then the intersection of these two languages can be recognized by the DFA
dfa3=(S1 x S2, (s1,s2), A1 x A2, f3)
where x means the cartesian product, and
f3((s'1,s'2),input)=(f1(s'1,input),f2(s'2,input))

Now, how you'd turn that back into a regexp is not so easy...
(but still doable)

--Ken
 
R

Richard Conroy

Hi everyone.

Just a question about regualar expression in Ruby. Is there a way to
check in each line of a document for always beginning with "23430000"
and somewhere on that same line another string 'CodeRed'?

line1: 23430000 @#$#$3455000CodeRed 24AAWERE 740000000

This is what I have so far when I import each textdata from another
file.


textdata.should =~ /23430000/ |CodeRed/

...the pipe was supposed to determine if CodeRed exists somewhere after
the identity code 23430000. However, it doesn't work like this. Also for
my code I am not using OR logic with it.

I just simply have to pimp http://www.rubular.com/

I don't think that I have closed that browser tab containing it in weeks.
Its killer feature is the ability to supply your own test data.
http://www.rubular.com

/^23430000.*CodeRed.*$/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top