Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Maybe this can be achieved through (extended) regular expressions, but I really don't know if or how. There seems to be a way to access "things that are found" by using $1, $2, … but I have no idea where to use that.

I want to search & replace (in multiple documents) an expression "with holes in it".

Example:

<someCodeAndOtherStuffThatAlwaysStaysTheSame
value="somePathThatAlwaysStaysTheSame/horse.mp3">
<moreCodeThatAlwaysStaysTheSame
src="samePathThatAlwaysStaysTheSame/horse.mp3"
<moreCodeThatAlwaysStaysTheSame>

should turn into

<audio controls="controls">
  <source src="horse.mp3" type="audio/mpeg">
</audio>

or possibly

<audio controls="controls">
  <source src="horse.mp3" type="audio/mpeg">
<embed height="50" width="100" src="horse.mp3">
</audio>

Of course, horse.mp3 is variable and the part that I desribed as a "hole".

I mainly use Bluefish Editor and gedit but a solution using the terminalwould be just as fine.

share|improve this question
add comment

1 Answer

up vote 0 down vote accepted

What you are looking for is called "Pattern Capture", where a particular pattern matched by a regular expression is saved in a variable. The details of how this is done depend on the language used (Perl, awk, sed or whatever).

Your problem is a bit more complicated because:

  1. You should not parse HTML with regular expressions

  2. Regular expressions become more complicated in most languages when your search pattern spans multiple lines.

  3. Since you have not included a sample of your actual code, it is harder for me to find a unique pattern with which to anchor my regular expression. In the script below I am using <moreCodeThatAlwaysStaysTheSame> and .someCodeAndOth you will need to change that to reflect actual unique patterns that flank the text you want to replace.

  4. You should not parse HTML with regular expressions

All that said, here is a Perl script that will replace the patterns you gave in your question:

#!/usr/bin/perl 
###############################################
# This sets the line separator to a string    #
# instead of a new line (\n). Use something   #
# that uniquely delimits the code you want to #
# replace.                                    #
###############################################
local $/="<moreCodeThatAlwaysStaysTheSame>";

#######################################################
# Read the input file, line by line. Remember that    #
# because of the previous command, a line is expected #
# to end with "<moreCodeThatAlwaysStaysTheSame>"      #
#######################################################
while (<>) {
#####################################################
# $str is what we want to replace the pattern with. #
# "XXX" will be replaced by the correct mp3.        #
#####################################################
    my $str=<<Eof;
 <audio controls="controls">
   <source src="XXXX" type="audio/mpeg">
<embed height="50" width="100" src="XXXX">
</audio>
Eof
###########################################################
# Match the entire string we will replace AND the         #
# mp3 we are looking for. In Perl (and other languages)   #
# placing a regex pattern in (parentheses) captures it.   #
# We can now refer to the 1st captured pattern as $1, the #
# second as $2 etc.                                       #
###########################################################
    /(.someCodeAndOth.+?src=.+\/(.+?\.mp3).+?$)/s;

###################################################
# Save the matches into variables, otherwise they #
# will be lost at the next match operation.       #
###################################################
    my ($match,$rep,$mp3)=($1,$1,$2);

###################################################
# Replace "XXXX" with the appropriate mp3 in $str #
###################################################
    $str=~s/XXXX/$mp3/g;

#########################################
# Replace the matched pattern with $str #
#########################################
    s/$match/$str/;

#################
# Print it out! #
#################
    print;
}

Save that script as foo.pl and run it on your file as follows:

perl foo.pl input_file.html > output_file.html
share|improve this answer
    
This is a great answer with useful example code. I want to stress one thing that has been mentioned by terdon: You should not parse HTML with regular expressions –  Shedeki May 7 '13 at 15:37
    
@Shedeki seems quite stressed already, it was my first and last point :). –  terdon May 7 '13 at 15:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.