Last occurrence of an expression

A

arfinmail

I was trying to extract the file name from a string like this:

aLine = "c:\\temp\\myFile.txt"

I found a regular expression for pearl which I modified to /[^\\]+$/
and it worked. Can anyone please explain this expression? I really
can't make sense of it :(

The way I look at it it's searching for the beginning of the file or a
slash, immediatly followed by the end of the string. But it's clearly
not what's happening.

I'm going to look for a way of doing it with the File object for
learning purposes :)

Another question: Given a string, is there a way to get all characters
between XXX and YYY but only if it does not contain the pattern ZZZ in
the middle?
Ex:
"This-XXX-is-an-YYY-example." => True
"This-XXX-is-ZZZ-an-YYY-example." => False
 
R

Robert Klemme

I was trying to extract the file name from a string like this:

aLine = "c:\\temp\\myFile.txt"

I found a regular expression for pearl which I modified to /[^\\]+$/
and it worked. Can anyone please explain this expression? I really
can't make sense of it :(

It extracts a string of non backslashes "[^\\]+" anchored at the end of
the sequence "$".
The way I look at it it's searching for the beginning of the file or a

No, the caret "^" inside the character group "[]" stands for "negation",
i.e., all characters *not* listed in the group. "[^0-9]" stands for "all
characters that are not digits".
slash, immediatly followed by the end of the string. But it's clearly
not what's happening.

I'm going to look for a way of doing it with the File object for
learning purposes :)

File#basename is the method you want.
Another question: Given a string, is there a way to get all characters
between XXX and YYY but only if it does not contain the pattern ZZZ in
the middle?
Ex:
"This-XXX-is-an-YYY-example." => True
"This-XXX-is-ZZZ-an-YYY-example." => False
s="This-XXX-is-an-YYY-example." => "This-XXX-is-an-YYY-example."
s.scan(/XXX(.*)YYY/) => [["-is-an-"]]
s.scan(/XXX(.*)YYY/).flatten.reject {|m| /ZZZ/ =~ m} => ["-is-an-"]
s.scan(/XXX(.*(?!ZZZ).*)YYY/).inject([]){|ar,m| ma=m[0];ar << ma unless
/ZZZ/=~ma;ar}
=> ["-is-an-"]
s="This-XXX-is-ZZZ-an-YYY-example." => "This-XXX-is-ZZZ-an-YYY-example."
s.scan(/XXX(.*)YYY/).flatten.reject {|m| /ZZZ/ =~ m} => []
s.scan(/XXX(.*(?!ZZZ).*)YYY/).inject([]){|ar,m| ma=m[0];ar << ma unless
/ZZZ/=~ma;ar}
=> []

Kind regards

robert
 
W

William James

Robert said:
Another question: Given a string, is there a way to get all characters
between XXX and YYY but only if it does not contain the pattern ZZZ in
the middle?
Ex:
"This-XXX-is-an-YYY-example." => True
"This-XXX-is-ZZZ-an-YYY-example." => False
s="This-XXX-is-an-YYY-example." => "This-XXX-is-an-YYY-example."
s.scan(/XXX(.*)YYY/) => [["-is-an-"]]
s.scan(/XXX(.*)YYY/).flatten.reject {|m| /ZZZ/ =~ m}

'XXX hi ZZZ ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[]

'XXX hi ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[[" hi ho "]]
 
R

Robert Klemme

William James said:
Robert said:
Another question: Given a string, is there a way to get all characters
between XXX and YYY but only if it does not contain the pattern ZZZ in
the middle?
Ex:
"This-XXX-is-an-YYY-example." => True
"This-XXX-is-ZZZ-an-YYY-example." => False
s="This-XXX-is-an-YYY-example."
=> "This-XXX-is-an-YYY-example."
s.scan(/XXX(.*)YYY/) => [["-is-an-"]]
s.scan(/XXX(.*)YYY/).flatten.reject {|m| /ZZZ/ =~ m}

'XXX hi ZZZ ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[]

'XXX hi ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[[" hi ho "]]

This is cute! I'd prefer to use this form, because (?!) does negative
look*ahead*:
'XXX hi ZZZ ho YYY'.scan(/XXX((?:.(?!ZZZ))*)YYY/) => []
'XXX hi ZZ ho YYY'.scan(/XXX((?:.(?!ZZZ))*)YYY/)
=> [[" hi ZZ ho "]]

I bet there are also differences in performance - although I didn't test.

Kind regards

robert
 
W

William James

Robert said:
'XXX hi ZZZ ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[]

'XXX hi ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[[" hi ho "]]

This is cute! I'd prefer to use this form, because (?!) does negative
look*ahead*:

After being limited to the simple regular expressions in Awk for
many years, I find the regular expressions in Ruby almost too good
to be true. Like you, I don't know whether mine is faster, but it
uses the advanced regexps of Ruby to good advantage.
 
R

Robert Klemme

William James said:
Robert said:
'XXX hi ZZZ ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[]

'XXX hi ho YYY'.scan(/XXX((?:(?!ZZZ).)*)YYY/)
[[" hi ho "]]

This is cute! I'd prefer to use this form, because (?!) does negative
look*ahead*:

After being limited to the simple regular expressions in Awk for
many years, I find the regular expressions in Ruby almost too good
to be true. Like you, I don't know whether mine is faster, but it
uses the advanced regexps of Ruby to good advantage.

Well, we all know that Awk stems from "awkward" (regardless what three
guys might claim) while Ruby is a gem. :)

Cheers

robert
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top