0

I have this code here

string.split(/(\w{1,}=)/).each_slice(1).map { |i| items << i }

items.map! do |i|
    i = i << str if i.to_s =~ /\w{1,}=/
end

puts items*''

And I want to modify certain items in the array based on regex, then return the full array with the modified items in it. This only returns the modified items. How do I achieve what I'm looking for?

EDIT: Ok, so say I'm trying to split a link using this regex:

page.php?site=blah&id=1

The link is split and added to the array which now contains

page.php?

site=

blah&

id=

1

What I want to do is append some value to the end of the elements ending with a =. This way, when I return the modified array as a string it would output like this:

page.php?site=(newval)&id=(newval)

3
  • 3
    Welcome to Stack Overflow. Please supply a sample input string and your expected output. When you have a question about code that isn't working right, we need to be able to replicate what you're seeing, and we need to be able to work from the same set of data. Please see "How to Ask". Commented Nov 6, 2015 at 18:34
  • Possible duplicate of Replacing number in URL after matching substring pattern. This question is nearly identical and in your case the URI Answer is the best way to go. Commented Nov 6, 2015 at 19:21
  • 1
    items = string.split(/(\w{1,}=)/) and no .each_slice(1).map... silliness. Commented Nov 6, 2015 at 20:07

2 Answers 2

1

You have several undefined variables in your example, which is very sloppy.

  1. each_slice(1) is equivalent to each(), so it's not clear why you are using each_slice(1). In any case, both each() and map() step through the items in an Array one by one, but each() returns the original Array unchanged. On the other hand, you use map() when you want to create a new Array that contains changes to the items.

  2. In the regex /\w{1,}/, there is a shortcut for the quantifier {1, }, and it's: +, so most people would write the regex as /\w+/, where + means 1 or more.

  3. I want to modify certain items in the array based on regex, then return the full array with the modified items in it.

Here is an example:

results = [1, 2, 3].map do |num|
  if num == 2
    num + 4
  else
    num - 1
  end
end

p results

--output:--
[0, 6, 2]

Your current attempt with map() doesn't return anything if the conditional fails. Note how the example above returns something both when the condition fails AND when the condition succeeds. map() replaces an item with whatever is returned for that item.

Now look at this example:

results = [1, 2, 3].map do |num|
  if num == 2
    num + 4
  end
end

p results

--output:--
[nil, 6, nil]

If you don't return something for an item, then map() will use nil for that item. In the example, if the condition num == 2 is true then num+4 is returned--but if num == 2 is false, nothing is returned.

Edit:

words = %w[
  page.php?
  site=
  blah&
  id=
  1
]    #=> words = ["page.php?", "site=", "blah&", "id=", "1"]

suffix = 'hello'

results = words.map do |word|
  if word.end_with?('=')   
    "#{word}#{suffix}"
  else
    word
  end
end

p results

--output:--
["page.php?", "site=hello", "blah&", "id=hello", "1"]
Sign up to request clarification or add additional context in comments.

2 Comments

I added further explanation in my OP for clarity.
@user3674736, See the bottom of my post for an example.
0

Instead of parsing a URL with a regex, have you considered using the addressable gem?

require 'addressable/uri'

uri = Addressable::URI.parse('page.php?site=blah&id=1&bar')
uri.query_values = uri.query_values.map do |k, v| 
  [k, v.is_a?(String) ? v << 'foo' : v] 
end
puts uri.to_s # => page.php?site=blahfoo&id=1foo&bar

This won't handle very complex query parameters (it will just pass them through).

You can use respond_to? :sub! and v.sub! /$/, 'foo' instead of checking types if that makes you uneasy. (I wouldn't use :<< or :concat because those are valid methods for Arrays.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.