index of string from beginning of line vs beginning of file

Discussion in 'Ruby' started by Jesse B., Mar 25, 2010.

  1. Jesse B.

    Jesse B. Guest

    I am trying to write a basic script to implement "silent comments"
    In the example anything from "input.txt" that is enclosed between "--/"
    and "/--" will not be output to "output.text" It appears that the
    problem I am having is that the opening string is indexed from beginning
    of file, whereas the closing string is indexed from beginning of line.
    So I would like to figure out why.
    Also when using Ruby1.9 there is an error message about using "each"
    with a string that I need to find a workaround to.
    any help is greatly appreciated. thanks in advance.
    here is the code:

    infile = IO.readlines('input.txt','').to_s
    outfile = File.new("output.txt", "w")
    begins = "--/"
    ends = "/--"
    start_ss = infile.index(begins)
    end_ss = infile.index(ends)
    infile[start_ss, end_ss] = ""

    infile.each {
    |i|
    outfile.write i
    }
    puts start_ss
    puts end_ss
    outfile.close()
    --
    Posted via http://www.ruby-forum.com/.
     
    Jesse B., Mar 25, 2010
    #1
    1. Advertising

  2. On Thu, Mar 25, 2010 at 5:19 PM, Jesse B. <> wrote:
    > I am trying to write a basic script to implement "silent comments"
    > In the example anything from "input.txt" that is enclosed between "--/"
    > and "/--" will not be output to "output.text" It appears that the
    > problem I am having is that the opening string is indexed from beginning
    > of file, whereas the closing string is indexed from beginning of line.
    > So I would like to figure out why.
    > Also when using Ruby1.9 there is an error message about using "each"
    > with a string that I need to find a workaround to.
    > any help is greatly appreciated. thanks in advance.
    > here is the code:
    >
    > infile =3D IO.readlines('input.txt','').to_s
    > outfile =3D File.new("output.txt", "w")
    > begins =3D "--/"
    > ends =3D "/--"
    > start_ss =3D infile.index(begins)
    > end_ss =3D infile.index(ends)
    > infile[start_ss, end_ss] =3D ""


    Check: http://ruby-doc.org/core/classes/String.html#M000771

    It says: If passed two Fixnum objects, returns a substring starting at
    the offset given by the first, and a length given by the second.

    So the second parameter should be the length of the text, not the
    index of the token. Try this:

    infile[start_ss, (end_ss - start_ss)] #untested

    > infile.each {
    > =A0|i|
    > =A0outfile.write i
    > =A0}
    > =A0puts start_ss
    > =A0puts end_ss
    > outfile.close()


    It's also better to use the block form of File.open to ensure proper
    closing, even after an exception.

    You could also try something like this:

    infile =3D File.read("input.txt")
    File.open("output.txt", "w") do |outfile|
    outfile.puts infile.split(%r{--/.*?/--}m)
    end

    Take into account that neither this nor the above solution with
    indexes supports nested comments.

    Jesus.
     
    Jesús Gabriel y Galán, Mar 25, 2010
    #2
    1. Advertising

  3. Jesse B.

    Jesse B. Guest

    Thank you Jesus,
    Your solution is much more elegant.
    However it leaves a blank line where my string was. any idea how to
    close that gap?

    i.e.

    opening text
    --/text to delete/--
    closing text

    now renders as:

    opening text

    closing text

    and what I am going for is:

    opening text
    closing text

    thanks again for all of your help!
    --
    Posted via http://www.ruby-forum.com/.
     
    Jesse B., Mar 25, 2010
    #3
  4. On Thu, Mar 25, 2010 at 9:09 PM, Jesse B. <> wrote:
    > Thank you Jesus,
    > Your solution is much more elegant.
    > However it leaves a blank line where my string was. any idea how to
    > close that gap?
    >
    > i.e.
    >
    > opening text
    > --/text to delete/--
    > closing text
    >
    > now renders as:
    >
    > opening text
    >
    > closing text
    >
    > and what I am going for is:
    >
    > opening text
    > closing text
    >
    > thanks again for all of your help!


    infile = File.read("input.txt")
    File.open("output.txt", "w") do |outfile|
    outfile.puts infile.split(%r{\n?--/.*?/--}m).join
    end

    Two changes:

    - I added an optional \n at the beggining of the matched area to cover
    that case, although there might be other corner cases.
    - I joined the array before writing it, because puts with an array
    prints a newline between each element.

    See if this works for you and test any other edge case regarding
    carriage returns. You can print what the split returns to see what you
    get in each case:

    infile = File.read("input.txt")
    File.open("output.txt", "w") do |outfile|
    splitted = infile.split(%r{\n?--/.*?/--}m)
    puts splitted.inspect
    outfile.puts splitted.join
    end

    Jesus.
     
    Jesús Gabriel y Galán, Mar 25, 2010
    #4
  5. Jesse B.

    Jesse B. Guest

    Thank you again for your help.

    I am finding that spaces before the "comment" cause it not to work.

    this works as expected:
    opening text
    --/text to delete/--
    closing text

    however this (one space before "comment")
    opening text
    --/text to delete/--
    closing text

    outputs a newline

    opening text

    closing text

    The command line output for the different cases looks like:
    C:\Ruby\bin\file_write>ruby jesus.rb
    ["opening text", "\nclosing text\n\n\n"]

    C:\Ruby\bin\file_write>ruby jesus.rb
    ["opening text\n ", "\nclosing text\n\n\n"]

    as you can see, there is the \n after opening text. The three \n at the
    end were present in the input.txt, so no problem.

    thank you for your time.

    Jesús Gabriel y Galán wrote:
    > On Thu, Mar 25, 2010 at 9:09 PM, Jesse B. <> wrote:
    >>
    >>
    >> thanks again for all of your help!

    >
    > infile = File.read("input.txt")
    > File.open("output.txt", "w") do |outfile|
    > outfile.puts infile.split(%r{\n?--/.*?/--}m).join
    > end
    >
    > Two changes:
    >
    > - I added an optional \n at the beggining of the matched area to cover
    > that case, although there might be other corner cases.
    > - I joined the array before writing it, because puts with an array
    > prints a newline between each element.
    >
    > See if this works for you and test any other edge case regarding
    > carriage returns. You can print what the split returns to see what you
    > get in each case:
    >
    > infile = File.read("input.txt")
    > File.open("output.txt", "w") do |outfile|
    > splitted = infile.split(%r{\n?--/.*?/--}m)
    > puts splitted.inspect
    > outfile.puts splitted.join
    > end
    >
    > Jesus.


    --
    Posted via http://www.ruby-forum.com/.
     
    Jesse B., Mar 26, 2010
    #5
  6. 2010/3/25 Jes=FAs Gabriel y Gal=E1n <>:
    > On Thu, Mar 25, 2010 at 9:09 PM, Jesse B. <> wrote:
    >> Thank you Jesus,
    >> Your solution is much more elegant.
    >> However it leaves a blank line where my string was. any idea how to
    >> close that gap?
    >>
    >> i.e.
    >>
    >> opening text
    >> --/text to delete/--
    >> closing text
    >>
    >> now renders as:
    >>
    >> opening text
    >>
    >> closing text
    >>
    >> and what I am going for is:
    >>
    >> opening text
    >> closing text
    >>
    >> thanks again for all of your help!

    >
    > infile =3D File.read("input.txt")
    > File.open("output.txt", "w") do |outfile|
    > =A0outfile.puts infile.split(%r{\n?--/.*?/--}m).join
    > end
    >
    > Two changes:
    >
    > - I added an optional \n at the beggining of the matched area to cover
    > that case, although there might be other corner cases.
    > - I joined the array before writing it, because puts with an array
    > prints a newline between each element.


    If you slurp in the whole file anyway then you can do

    content =3D File.read "input.txt"
    content.gsub! %r{--/.*?/--}m, ''

    File.open "output.txt", "w" do |out|
    out.write content
    end

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Mar 26, 2010
    #6
  7. Jesse B.

    Jesse B. Guest

    Thank You Robert,
    I tried running this and unfortunately it shows the line break (newline)
    with or without the leading space before the "comment".

    So I think Jesus is unto something with the "joined the array before
    writing it because puts with an array prints a newline between each
    element."

    Now I just need to figure out how to have it not do the newline when
    there are spaces before the "comment"
    thanks for your time.


    Robert Klemme wrote:
    > 2010/3/25 Jes�s Gabriel y Gal�n <>:
    >>> closing text
    >>> closing text

    >> - I added an optional \n at the beggining of the matched area to cover
    >> that case, although there might be other corner cases.
    >> - I joined the array before writing it, because puts with an array
    >> prints a newline between each element.

    >
    > If you slurp in the whole file anyway then you can do
    >
    > content = File.read "input.txt"
    > content.gsub! %r{--/.*?/--}m, ''
    >
    > File.open "output.txt", "w" do |out|
    > out.write content
    > end
    >
    > Kind regards
    >
    > robert


    --
    Posted via http://www.ruby-forum.com/.
     
    Jesse B., Mar 26, 2010
    #7
  8. On Fri, Mar 26, 2010 at 5:17 PM, Jesse B. <> wrote:
    > Thank You Robert,
    > I tried running this and unfortunately it shows the line break (newline)
    > with or without the leading space before the "comment".
    >
    > So I think Jesus is unto something with the "joined the array before
    > writing it because puts with an array prints a newline between each
    > element."
    >
    > Now I just need to figure out how to have it not do the newline when
    > there are spaces before the "comment"
    > thanks for your time.


    I think there's no solution to that. I mean, the requirement is to
    remove what's inside the comments, and that leaves a line with a
    single space. Both my solution and Robert's do exactly that (I think
    Robert's solution is the better one).

    What you are asking now is for an additional condition, that it might
    be that if after removing the comments there's an empty line (a line
    with only spaces), that should be removed too.

    content = File.read "input.txt"
    content.gsub! %r{--/.*?/--}m, ''
    content.gsub! %r{\A\s+\z}, '' # untested and i think you might to
    remove a \n in this case too, give it a try.

    File.open "output.txt", "w" do |out|
    out.write content
    end


    Or maybe the condition is to remove all the whitespace and \n that
    surround the comments.

    content = File.read "input.txt"
    content.gsub! %r{[\n\s]*--/.*?/--[\n\s]*}m, '' #untested also, but
    you get the idea.

    File.open "output.txt", "w" do |out|
    out.write content
    end

    Hope this helps,

    Jesus.
     
    Jesús Gabriel y Galán, Mar 26, 2010
    #8
  9. On 03/26/2010 09:48 PM, Jesús Gabriel y Galán wrote:
    > On Fri, Mar 26, 2010 at 5:17 PM, Jesse B. <> wrote:
    >> Thank You Robert,
    >> I tried running this and unfortunately it shows the line break (newline)
    >> with or without the leading space before the "comment".
    >>
    >> So I think Jesus is unto something with the "joined the array before
    >> writing it because puts with an array prints a newline between each
    >> element."
    >>
    >> Now I just need to figure out how to have it not do the newline when
    >> there are spaces before the "comment"
    >> thanks for your time.

    >
    > I think there's no solution to that. I mean, the requirement is to
    > remove what's inside the comments, and that leaves a line with a
    > single space. Both my solution and Robert's do exactly that (I think
    > Robert's solution is the better one).
    >
    > What you are asking now is for an additional condition, that it might
    > be that if after removing the comments there's an empty line (a line
    > with only spaces), that should be removed too.
    >
    > content = File.read "input.txt"
    > content.gsub! %r{--/.*?/--}m, ''
    > content.gsub! %r{\A\s+\z}, '' # untested and i think you might to
    > remove a \n in this case too, give it a try.
    >
    > File.open "output.txt", "w" do |out|
    > out.write content
    > end
    >
    >
    > Or maybe the condition is to remove all the whitespace and \n that
    > surround the comments.
    >
    > content = File.read "input.txt"
    > content.gsub! %r{[\n\s]*--/.*?/--[\n\s]*}m, '' #untested also, but
    > you get the idea.
    >
    > File.open "output.txt", "w" do |out|
    > out.write content
    > end
    >
    > Hope this helps,


    A bit more to play with

    content = File.read "input.txt"
    content.gsub! %r{^[ \t]*--/(?:.(?!/--))*.?/--\s*?$\s}m, ''
    content.gsub! %r{[ \t]*--/(?:.(?!/--))*.?/--[ \t]*}m, ' '

    File.open "output.txt", "w" do |out|
    out.write content
    end


    I used this for testing:


    robert@fussel:~$ cat input.txt
    1. before after
    X1.1
    before --/ comment
    comment /-- after
    X1.2
    2. before
    X2.1
    before --/ comment
    comment /--
    X2.2
    3. after
    X3.1
    --/ comment
    comment /-- after
    X3.2
    4. -
    X4.1
    --/ comment
    comment /--
    X4.2
    5. end
    robert@fussel:~$

    ;-)

    Cheers

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Mar 26, 2010
    #9
  10. Jesse B.

    Jesse B. Guest

    Jesse B., Mar 27, 2010
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kosh
    Replies:
    9
    Views:
    326
    Andrew Dalke
    Oct 17, 2004
  2. scad
    Replies:
    23
    Views:
    1,220
    Alf P. Steinbach
    May 17, 2009
  3. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    359
    Tomasz Chmielewski
    Mar 4, 2008
  4. PerlFAQ Server
    Replies:
    0
    Views:
    402
    PerlFAQ Server
    Feb 24, 2011
  5. Rivka Miller
    Replies:
    16
    Views:
    311
    Joel Goldstick
    Oct 26, 2012
Loading...

Share This Page