Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PERL regexp puzzlers.... 1

Status
Not open for further replies.

Numbski

MIS
Mar 27, 2001
56
0
0
US
Heh, this is throwing me for a loop, figured I'd share the wealth and see if anyone can get it straight. :)

Number 1. I am writing a PERL program that will be run locally on various operating systems. All of those OS's use "/" to seperate out it's directory structure except for windows, which uses "\", that also happens to be PERL's escape character. I will have users inputing two directories off of a form, one will be where they are keeping some playlists, and another is where I can copy mp3 files to. In order to keep the rest of my code uniform, I'd like to convert those to strings so that all "\" are replaced with "/". PERL doesn't care, in fact if I thought I could get all windows users to write out "c:/mp3/playlists/" when I ask for their playlist directory, I'd do it. But as my old programming teacher always taught me, you have to cater to the lowest common denominator. :) Here's what I have so far:

$pldir=~s/\\/\//;

Presume that $pldir contains my playlist directory, say what I stated above c:\mp3\playlists, and the syntax is like this:

~s/what I'm looking for/what I want to replace it with/;

My presumption in this case that since both "\" and "/" are special characaters, thus they must be escaped, leaving me with \\ and \/, thus the garbled mess of a regular expression you see above.

Number 2. Okay, again I have to cater to the lowest common denominator. I'm asking people for directories. Making the presumption that I've succeeding and making everything look like Unix from the first problem, there are essentially two types of input I'll get from this query:

c:/mp3/playlists
c:/mp3/playlists/

Now again, I could implore people to always put that last slash in, but who ever listens to the programmer anyway? :) I need to run a regular expression against this that checks THE LAST CHARACTER ONLY. If it's a forward slash, leave it alone, if it's anything else, then resave the $pldir variable, or $pldir=$pldir."/";

That seems straightforward enough, but I swear I've search all over for a regex that checks only that last character. Go fig. Need some help with this one.

Number 3. If you've ever opened a WinAmp Playlist in a text editor before, the format of it is something like this:

#Your Mix Playlist\n
c:\mp3\mysong.mp3\n
yoursong.mp3\n
\\myserver\thatsong.mp3\n

The first thing you'll notice is that there are no \n in the one on your computer. Well, they are there. I found this out the hard way. A hard return is ALWAYS a newline character, or \n. Learn to love chomp(); :)

For the moment, I'm running a pair of regular expressions. The first is that if the string contains a "#", leave it out of the array. The second checks for ":", and if it doesn't contain that character, then you have to add the $pldir to the front of it, so that when we do the copy, it contains the full path. That works if we're only dealing with a windows system (linux, Unix, and generally any posix system begins with a "/") and no network shares. I need to develop a testing routine that puts each line of that list into an array that is not a comment, and each line have it's full, true system path. This includes unix based systems, which I suppose a regexp testing the first characther for a "/" might work, but I don't remember offhand how winamp deals with a song in a direct subdirectory to the playlist itself. Does it simply preceed it with a slash, or does it put the full system path?

Number 5. Yes, this is getting to be quite the homework assignment, isn't it? :) In order to properly use the built-in perl copy command, the syntax is:

copy (sourcefile,targetfile);

Unlike the copy command that us windows users are accustomed to, where you use copy myfile c:\windows, which would place myfile in the windows directory, in perl, using that command would take myfile, rename it to windows, and place it in c:\. In PERL, it has to be:

copy (myfile,c:\windows\myfile);

Which is fine, except that at the moment, the way I'm getting the very tail end of what the playlist gave me (which should be something like c:\mp3\mysong.mp3) is to split the string at "\" and load each section into an array, counting each cycle through the loop, subtract one, then save that last bit to a variable. After I switch all the "\" to "/", I might be able to get away with just change the split to "/", but I can't help but feel the more elegant solution would be to run a regexp that starts at the end of the string, and works it's way to the front until it hits a "/", then saves that. I've looked high and low and have found nothing like this. Help?

Wow what a novel. Any ideas?

Numbski
 
ah, a young'un.

okay. you have alot of the right ideas, but were often implementing them slightly off.

let's see. before anything else, a little regex lesson.

to find the end of a string, the last character, that is, you need to use '$', which, when used as the end of a regular expression, means the end of the string. NOT the last character, mind you, just the end. so you'll need a regular expression that matches one character followed immediately my the end of the string:[tt]
m/.$/
[/tt]
that'll do that.
one thing you can do with regular expressions is you don't have to use '/' as the delimiter, you can use any character, or even parentheses, brackets, whatever. just do something like:[tt]
s~match~replace~;[/tt]
and that way you can use the '/' character without escaping it, and your regular expressions will look alot cleaner.
now, there is a character in regexes, the '|', which you can use to say 'or'. now, at some point, if you're slicing up a path name and you don't know if there's going to be a '/' or a '\', you can use a regex like:[tt]
m~/|\\~
[/tt]
and that will match either. so for your split, use that regular expression and you won't have to first go through and replace things. then also, for the playlist checking, you can have:[tt]
m~^/|^\w:~[/tt]

notice the '^', which, like '$', doesn't match any characters, but this time matches the beginning of a line. '\w' means any word character (letters, etc.), so it'll match A, b, C or whatever.

oh, gotta go. someone else can pick up where i left off.

oh, and i didn't know perl had a built in copy subroutine...:) "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."
 
Well, I sorta lied there. :)

use File::Copy

THEN I can use the copy (sourcefile,targetfile); structure.

I'm going to re-read that a few times and try to let it sink in. If it helps my programming technique is usually solid, but I learned QuickBasic, then JavaScript, and now this, so my syntax is usually what is screwed up to no end. ;)

Numbski
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top