Drop 1st and last particular character

What is the most efficient way to drop '#' from the first place and last
place if any.

for example:
if input= #hithere# then output = hithere
if input = hithere# then output =hithere
if input = #hithere then output =hithere
if input = hithere then output=hithere

···

--
Posted via http://www.ruby-forum.com/.

Simplest method is to use Regex.

···

2012/10/16 ajay paswan <lists@ruby-forum.com>

What is the most efficient way to drop '#' from the first place and last
place if any.

for example:
if input= #hithere# then output = hithere
if input = hithere# then output =hithere
if input = #hithere then output =hithere
if input = hithere then output=hithere

--
Posted via http://www.ruby-forum.com/\.

or both regexp combined:
"#hit#here#".gsub(/(^#)|(\#$)/,'') #=> "hit#here"

···

--
Posted via http://www.ruby-forum.com/.

Have you considered python?

my_str = "#hi#there#"
print(my_str.strip('#'))

--output:--
hi#there

···

--
Posted via http://www.ruby-forum.com/.

You didn't mention what if you have three times '#'.
e.g. input = "#1234#567#
I assume you want output = "1234#567"
Use the String function "sub" which substitute from the first occurrence only, on the input,
Then reverse the input and use it again (to remove last occurrence)
e.g.:
myString.sub!('#','')
myString.reverse!.sub!('#','').reverse!
This will keep all the '#' chars in between.

Sagy

···

-----Original Message-----
From: ajay paswan [mailto:lists@ruby-forum.com]
Sent: Tuesday, October 16, 2012 9:06 AM
To: ruby-talk ML
Subject: Drop 1st and last particular character

What is the most efficient way to drop '#' from the first place and last place if any.

for example:
if input= #hithere# then output = hithere if input = hithere# then output =hithere if input = #hithere then output =hithere if input = hithere then output=hithere

--
Posted via http://www.ruby-forum.com/.

output = input.gsub(/^#/, "")

···

On Tuesday, 16 October 2012 at 6:27 PM, Иван Бишевац wrote:

Simplest method is to use Regex.

2012/10/16 ajay paswan <lists@ruby-forum.com (mailto:lists@ruby-forum.com)>
> What is the most efficient way to drop '#' from the first place and last
> place if any.
>
> for example:
> if input= #hithere# then output = hithere
> if input = hithere# then output =hithere
> if input = #hithere then output =hithere
> if input = hithere then output=hithere
>
> --
> Posted via http://www.ruby-forum.com/\.

We can also combine by positively matching:

irb(main):001:0> s = "#hit#here#"
=> "#hit#here#"
irb(main):002:0> s = s[/^#?(.*?)#?\z/, 1]
=> "hit#here"

All possible combinations

irb(main):003:0> %w{hi#there #hi#there hi#there# #hi#there#}.each {|s|
p s[/^#?(.*?)#?\z/, 1]}
"hi#there"
"hi#there"
"hi#there"
"hi#there"
=> ["hi#there", "#hi#there", "hi#there#", "#hi#there#"]

Kind regards

robert

···

On Tue, Oct 16, 2012 at 9:38 AM, Hans Mackowiak <lists@ruby-forum.com> wrote:

or both regexp combined:
"#hit#here#".gsub(/(^#)|(\#$)/,'') #=> "hit#here"

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Sagy Drucker wrote in post #1080132:

You didn't mention what if you have three times '#'.
e.g. input = "#1234#567#
I assume you want output = "1234#567"
Use the String function "sub" which substitute from the first occurrence
only, on the input,
Then reverse the input and use it again (to remove last occurrence)
e.g.:
myString.sub!('#','')
myString.reverse!.sub!('#','').reverse!
This will keep all the '#' chars in between.

Sagy

No Sagy, that's not a good method:

"1#1234#567#1".sub!('#','').reverse!.sub!('#','').reverse!
=> "11234#5671"

···

--
Posted via http://www.ruby-forum.com/\.

Few remarks: you do not need the capturing groups. And using \A and
\z is better since it will be really the beginning and the end of the
string. Consider

irb(main):008:0> s = "aaaa\n#bbb#cc#\n"
=> "aaaa\n#bbb#cc#\n"
irb(main):009:0> s.gsub /^#|\#$/, ''
=> "aaaa\nbbb#cc\n"

Note: the backslash before the second # is needed to avoid string
interpolation confusion.

According to the original specification neither the # before "bbb" has
to be removed nor the one after "cc". On the contrary with \A and \z
the string remains unchanged which is what should happen:

irb(main):010:0> s.gsub /\A#|#\z/, ''
=> "aaaa\n#bbb#cc#\n"
irb(main):011:0> s == s.gsub(/\A#|#\z/, '')
=> true

Kind regards

robert

···

On Tue, Oct 16, 2012 at 9:38 AM, Hans Mackowiak <lists@ruby-forum.com> wrote:

or both regexp combined:
"#hit#here#".gsub(/(^#)|(\#$)/,'') #=> "hit#here"

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

this does not work if there is no '#'

1.9.3p194 :001 > myString = '123'
  => "123"
1.9.3p194 :0ß2 > myString.reverse!.sub!('#','').reverse!
NoMethodError: undefined method `reverse!' for nil:NilClass

···

Am 17.10.2012 09:39, schrieb Sagy Drucker:

You didn't mention what if you have three times '#'.
e.g. input = "#1234#567#
I assume you want output = "1234#567"
Use the String function "sub" which substitute from the first occurrence only, on the input,
Then reverse the input and use it again (to remove last occurrence)
e.g.:
myString.sub!('#','')
myString.reverse!.sub!('#','').reverse!
This will keep all the '#' chars in between.

--
<https://github.com/stomar/&gt;

Oh, I'm an idiot, the end as well:

output = input.gsub(/^#/, "").gsub(/\#$/, "")

(escape # to prevent interpolation)

···

On Tuesday, 16 October 2012 at 6:28 PM, Arlen Cuss wrote:

output = input.gsub(/^#/, "")

On Tuesday, 16 October 2012 at 6:27 PM, Иван Бишевац wrote:

> Simplest method is to use Regex.
>
> 2012/10/16 ajay paswan <lists@ruby-forum.com (mailto:lists@ruby-forum.com)>
> > What is the most efficient way to drop '#' from the first place and last
> > place if any.
> >
> > for example:
> > if input= #hithere# then output = hithere
> > if input = hithere# then output =hithere
> > if input = #hithere then output =hithere
> > if input = hithere then output=hithere
> >
> > --
> > Posted via http://www.ruby-forum.com/\.
>

irb(main):010:0> s.gsub /\A#|#\z/, ''
=> "aaaa\n#bbb#cc#\n"
irb(main):011:0> s == s.gsub(/\A#|#\z/, '')
=> true

Kind regards

robert

This looks like the best solution.

···

--
Posted via http://www.ruby-forum.com/\.

Tangentially, it just occurred to me that ruby's regular expression
engine does the same thing that javascript's does, when globally
replacing /X*$/ . It arose when someone wanted to replace any number
(or none) of a character at the start and end of a string with exactly
one of that character.

irb(main):001:0> 'foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):002:0> '#foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):003:0> '##foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):004:0> 'foo#'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"
irb(main):005:0> 'foo##'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"
irb(main):006:0> '##foo##'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"

The original javascript question came up on StackOverflow
<http://stackoverflow.com/questions/6147609/how-to-remove-duplicate-character-at-the-end-of-a-string-in-regex>

I blogged about it here:
http://matthew.kerwin.net.au/blog/20110608_javascript_global_regexp

···

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/
  ABN: 59-013-727-651

  "You'll never find a programming language that frees
  you from the burden of clarifying your ideas." - xkcd

One should use gsub! though if the old String does not need to be
retained - that saves memory because the String is changed in place.

If the old String should be retained this approach might actually be
more efficient since AFAIK both strings share the char buffer if I am
not mistaken:
s = s[/^#?(.*?)#?\z/, 1]

But this is micro optimizing already so better pick what suits you best.

Kind regards

robert

···

On Wed, Oct 17, 2012 at 1:58 PM, Joel Pearson <lists@ruby-forum.com> wrote:

irb(main):010:0> s.gsub /\A#|#\z/, ''
=> "aaaa\n#bbb#cc#\n"
irb(main):011:0> s == s.gsub(/\A#|#\z/, '')
=> true

This looks like the best solution.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Tangentially, it just occurred to me that ruby's regular expression
engine does the same thing that javascript's does, when globally
replacing /X*$/ .

This behavior is common with most regexp engines (at least I don't
know any which does _not_ behave like this). All regular expressions
X* can match the empty string - anywhere in the input.

irb(main):022:0> "####".scan /\w*/
=> ["", "", "", "", ""]

And, when anchoring a portion of the match expression at the end and
have repetition in that match you need to make sure that the
characters are not eaten by other parts of the regexp.

"naive" approach:

irb(main):026:0> %w{aaa aab abb bbb}.each {|s| /.*(b*)\z/ =~ s; printf
"%p: 1:%p\n", s, $1}
"aaa": 1:""
"aab": 1:""
"abb": 1:""
"bbb": 1:""
=> ["aaa", "aab", "abb", "bbb"]

Working approaches:

1. reduce greed

irb(main):027:0> %w{aaa aab abb bbb}.each {|s| /.*?(b*)\z/ =~ s;
printf "%p: 1:%p\n", s, $1}
"aaa": 1:""
"aab": 1:"b"
"abb": 1:"bb"
"bbb": 1:"bbb"
=> ["aaa", "aab", "abb", "bbb"]

2. negative lookbehind

irb(main):028:0> %w{aaa aab abb bbb}.each {|s| /.*(?<!b)(b*)\z/ =~ s;
printf "%p: 1:%p\n", s, $1}
"aaa": 1:""
"aab": 1:"b"
"abb": 1:"bb"
"bbb": 1:"bbb"
=> ["aaa", "aab", "abb", "bbb"]

Note though the special case where there is only one alternative with
a match anchored at the end:

irb(main):045:0> for b in body; for pre in segm; for post in segm;
s="#{pre}#{b}#{post}"; printf "%p -> %p\n",s,s[/#*\z/]; end end end
"" -> ""
"#" -> "#"
"##" -> "##"
"#" -> "#"
"##" -> "##"
"###" -> "###"
"##" -> "##"
"###" -> "###"
"####" -> "####"
"foo" -> ""
"foo#" -> "#"
"foo##" -> "##"
"#foo" -> ""
"#foo#" -> "#"
"#foo##" -> "##"
"##foo" -> ""
"##foo#" -> "#"
"##foo##" -> "##"
=> ["", "foo"]

Here, the simple expression works since the # are not eaten by other
portions of the regexp.

It arose when someone wanted to replace any number
(or none) of a character at the start and end of a string with exactly
one of that character.

irb(main):001:0> 'foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):002:0> '#foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):003:0> '##foo'.gsub(/\A#*|#*\Z/, '#')
=> "#foo#"
irb(main):004:0> 'foo#'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"
irb(main):005:0> 'foo##'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"
irb(main):006:0> '##foo##'.gsub(/\A#*|#*\Z/, '#')
=> "#foo##"

If one regexp should be used in this case the negative lookbehind is a
viable option since there is no preceding part in this alternative
which we can make non greedy:

irb(main):044:0> for b in body; for pre in segm; for post in segm;
s="#{pre}#{b}#{post}"; printf "%p -> %p\n",s,s.gsub(/\A#*|(?<!#)#*\z/,
'#'); end end end
"" -> "#"
"#" -> "#"
"##" -> "#"
"#" -> "#"
"##" -> "#"
"###" -> "#"
"##" -> "#"
"###" -> "#"
"####" -> "#"
"foo" -> "#foo#"
"foo#" -> "#foo#"
"foo##" -> "#foo#"
"#foo" -> "#foo#"
"#foo#" -> "#foo#"
"#foo##" -> "#foo#"
"##foo" -> "#foo#"
"##foo#" -> "#foo#"
"##foo##" -> "#foo#"
=> ["", "foo"]

I blogged about it here:
Matthew Kerwin :: Blog :: JS: <code>/x*$/</code> in global replace

Turns out with Oniguruma there *is* a way to do it with a single
regexp. In fact any regexp engine with lookbehind will do.

Reference: サービス終了のお知らせ

Kind regards

robert

···

On Thu, Oct 18, 2012 at 2:51 AM, Matthew Kerwin <matthew@kerwin.net.au> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/