Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Most efficient way to remove some text from a string

by adamZ88 (Beadle)
on Dec 06, 2016 at 20:24 UTC ( [id://1177327]=perlquestion: print w/replies, xml ) Need Help??

adamZ88 has asked for the wisdom of the Perl Monks concerning the following question:

I have three potential scenarios. A String could either represent an artist, an album or a song. Unfortunately each string is going to be preceded by a path. Here is an example of each of the scenarios.

/Volumes/WD/Not Migrating/Music/Ana Tijoux (An Artist)

/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin (An Album)

/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin/Luchin.m4a (A Song)

I the most efficient regular expression to trim "/Volumes/WD/Not Migrating/Music/" from my original string. Once this is complete, this will be assigned to a variable. I then need a regular expression to determine the number of "/". This will help me determine if the that variable contains an Artist (0 "/"), an Album (1 "/") , A song (2 "/")

Lastly, is there a way to print bullet points in Perl? Depending on the number of "/" is how many indents i will print the variable with.

Replies are listed 'Best First'.
Re: Most efficient way to remove some text from a string
by Corion (Patriarch) on Dec 06, 2016 at 20:30 UTC

    You haven't shown the relevant parts of the code you've already written, so my advice remains pretty generic:

    To trim the string, see substr.

    To find the number of levels and get at the elements, then see split.

    To print bullet points, see print and maybe *, or, if your terminal is unicode-aware, any of the fancy Unicode glyphs. Also see \N{}, respectively print "\N{BULLET}".

      I have very little done so far

      open(FILEREAD, "</home/zzz/Desktop/Scripting/usb/musicLibrary.txt"); while ($aPath = <FILEREAD>) {chomp ($aPath); my $file =~ s/$sPath/Totally/; print "This Path $file \n\n";} close (FILEREAD);

        This prints only the artist, album or track name

        #!perl use strict; #my $infile = '/home/zzz/Desktop/Scripting/usb/musicLibrary.txt'; #open IN,'<',$infile or die "Could not open $infile $!"; #while (<IN>){ while (<DATA>){ chomp; my @f = split '/',$_; my $tab = ' ' x (@f-6); print $tab.$f[-1]."\n"; } __DATA__ /Volumes/WD/Not Migrating/Music/Ana Tijoux /Volumes/WD/Not Migrating/Music/Ana Tijoux/Luchin /Volumes/WD/Not Migrating/Music/Ana Tijoux/Luchin/Luchin.m4a /Volumes/WD/Not Migrating/Music/Ana Tijoux/Kaos/ /Volumes/WD/Not Migrating/Music/Ana Tijoux/Kaos/Intro.m4a /Volumes/WD/Not Migrating/Music/Ana Tijoux/Kaos/Gol.m4a /Volumes/WD/Not Migrating/Music/Ana Tijoux/Kaos/Despabílate.m4a
        poj
Re: Most efficient way to remove some text from a string
by tybalt89 (Monsignor) on Dec 06, 2016 at 20:46 UTC

    With some guessing (and fixing what I think is a typo)

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1177327 use strict; use warnings; my $prefixlength = length '/Volumes/WD/Not Migrating/Music/'; while(<DATA>) { substr $_, 0, $prefixlength, ''; my $indent = tr#/##; print " " x $indent, "* $_"; } __DATA__ /Volumes/WD/Not Migrating/Music/Ana Tijoux /Volumes/WD/Not Migrating/Music/Ana Tijoux/Luchin /Volumes/WD/Not Migrating/Music/Ana Tijoux/Luchin/Luchin.m4a

      Very Very Close. The first part to trim the unwanted path is working correctly. However, everything printed without any indents(tabs) and with an asterisk.

        Are you printing to a terminal or to a web page?

Re: Most efficient way to remove some text from a string
by Marshall (Canon) on Dec 06, 2016 at 21:26 UTC
    I doubt that you will actually need "the most efficient way" which would mean some sort of performance objective to me. My advice is to do the job in a way that you can understand. All of the Perl ways will run quickly. Worry about efficient after you get something that works and that you understand how it works.

    I'm not sure what the indentation level is exactly. Could it be that this "Eminem" token should be deleted it it is there?

    use strict; use warnings; use Data::Dumper; my @cases=( '/Volumes/WD/Not Migrating/Music/Ana Tijoux (An Artist)', '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin (An Album)', '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin/Luchin.m4a ( +A Song)'); foreach my $case (@cases) { $case =~ s|^.+Music/||; # remove /Volumes/WD/Not Migrating/Music/ $case =~ s|\(.+\)||; # remove trailing (An Artist), etc. print "\nLooking at case:$case...\n"; my @parts = split ('/',$case); my $indent = 0; if (@parts == 3){$indent=1;} elsif (@parts==4) {$indent=2;} print "# parts=".@parts," , the indent level=$indent\n"; print "indent line is next:\n"; print "\t"x$indent,"$parts[-1]\n"; #use only last part?? and indent +?? print "all parts:\n"; print Dumper \@parts; } __END__ PRINTOUT: Looking at case:Ana Tijoux ... # parts=1 , the indent level=0 indent line is next: Ana Tijoux all parts: $VAR1 = [ 'Ana Tijoux ' ]; Looking at case:Eminem/Ana Tijoux/Luchin ... # parts=3 , the indent level=1 indent line is next: Luchin all parts: $VAR1 = [ 'Eminem', 'Ana Tijoux', 'Luchin ' ]; Looking at case:Eminem/Ana Tijoux/Luchin/Luchin.m4a ... # parts=4 , the indent level=2 indent line is next: Luchin.m4a all parts: $VAR1 = [ 'Eminem', 'Ana Tijoux', 'Luchin', 'Luchin.m4a ' ];

      You are correct! I may be getting more confused trying to make things in the most efficient way with my level of knowledge. I did mean what I said about the most efficient way, but I do see your point. For a newbie this makes things more confusing. I appreciate your feedback, I will try your suggestions later.

        Hi adamZ88,

        You wrote: "I did mean what I said about the most efficient way, but I do see your point." I am not sure that you do indeed "get it yet". There will be no user perceptible speed difference between any code in this thread. Forget it! No difference! All of these program snippets are I/O bound under Windows.

        There are 2 basic approaches to your first problem of how to remove the ...Music stuff from the beginning of the string. (1)involves counting a number of characters in a "prototype" and then removing that exact number of characters from the input string. (2) Use a regular expression like I did to remove the first part of the file path. This is a much more flexible approach and can be used where the complete path to the Music differs.

        Your spec and the introduction of "Eminem" confused me and others. Hence the strange mapping between number of slashes and indentation level in my code.

        My advice is to run all of the proposed solutions on your machine and see if you can figure out how all of them work.

Re: Most efficient way to remove some text from a string
by AnomalousMonk (Archbishop) on Dec 06, 2016 at 20:44 UTC

    I don't understand the "... if the that variable contains an Artist (0 "/"), an Album (1 "/") , A song (2 "/")" part, but here's this:

    c:\@Work\Perl\monks>perl -wMstrict -le "my @ra = ( '/Volumes/WD/Not Migrating/Music/Ana Tijoux', '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin', '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin/Luchin.m4 +a', ); print qq{'$_'} for @ra; ;; my $dir_level = qr{ / [^/]+ }xms; ;; my $n = 4; s{ \A (?: $dir_level){$n} / }{}xms for @ra; print qq{'$_'} for @ra; ;; for my $s (@ra) { my $n_fs = $s =~ tr{/}{}; my $indent = ' '; printf qq{%s'$s' \n}, $indent x $n_fs; } " '/Volumes/WD/Not Migrating/Music/Ana Tijoux' '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin' '/Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin/Luchin.m4a' 'Ana Tijoux' 'Eminem/Ana Tijoux/Luchin' 'Eminem/Ana Tijoux/Luchin/Luchin.m4a' 'Ana Tijoux' 'Eminem/Ana Tijoux/Luchin' 'Eminem/Ana Tijoux/Luchin/Luchin.m4a'

    Update: Changed name of regex variable  $dir to more descriptive  $dir_level


    Give a man a fish:  <%-{-{-{-<

      Sorry for the confusion. What I meant is that once I have removed the unnecessary part of the path, I would check the remaining string and count the number of forward slashes"/". If there are 0 forward slashes, this string represented an artist, if there is 1 forward slash, this string represents an album, 2 forward slashes represents a song.

        I was confused because you seem to have  /Eminem running wild through your example paths. Others have assumed this is a typo, and you've never denied this. (Nor ever confirmed it...)


        Give a man a fish:  <%-{-{-{-<

Re: Most efficient way to remove some text from a string
by BillKSmith (Monsignor) on Dec 07, 2016 at 05:34 UTC
    Strip the directory with a substitute. Count remaining slashes with tr.
    use strict; use warnings; my @types = qw( Artist Album Song Song); while (<DATA>) { s!^/Volumes/WD/Not Migrating/Music/!!; my $type = $types[ tr/\//\// ]; printf "%-6s : %-80s\n", $type, $_; } __DATA__ /Volumes/WD/Not Migrating/Music/Ana Tijoux /Volumes/WD/Not Migrating/Music/Eminem/Ana /Volumes/WD/Not Migrating/Music/Eminem/Ana Tijoux/Luchin/Luchin.m4a Output: Artist : Ana Tijoux Album : Eminem/Ana Song : Eminem/Ana Tijoux/Luchin/Luchin.m4a
    Bill

      Bill, thank you for your explanation, it greatly helps. I follow what you are saying, can you please expand on how "tr" counts the remaining slashes and how the printf is being used. This would help me actually learn this content and not just simply use it because I am told. Thanks

        I'm not sure just who you're replying to, but in general ...

        ... how "tr" counts the remaining slashes ...

        Please see discussion of  tr/// operator in Quote-Like Operators section of perlop. In particular, please see examples 2-4 in Examples sub-section.

        ... how the printf is being used.

        Please see printf; see sprintf for discussion of format specifiers.


        Give a man a fish:  <%-{-{-{-<

Re: Most efficient way to remove some text from a string
by Guntherssl (Initiate) on Dec 06, 2016 at 23:38 UTC
    Brb, realized it wasn't counting mmatches

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1177327]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-03-28 23:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found