Suppose I have a url
xyz.com/param1=abc¶m2=123¶m3=!##
Each parameter can have many values like:
param1 = abc, xyz, qwe
param2 = 123, 456, 789
param3 = !##, $%^, &*(
All the parameters and values will be read from an excel file. There can be n number of parameters and each may have any number of values.
I want to generate all the combinations which can be formed using all values of each parameters.
Output will be like:
xyz.com/param1=abc¶m2=123¶m3=!##
xyz.com/param1=xyz¶m2=456¶m3=!##
xyz.com/param1=qwe¶m2=123¶m3=!##
xyz.com/param1=qwe¶m2=456¶m3=!##
xyz.com/param1=xyz¶m2=789¶m3=$%^
...
..
and so on
besides the previous comment in your post, you need construct some nested loops.
I will assume you have a bash shell available (since you hadn't specified your wanted language).
for I in 'abc' 'xyz' 'qwe'
do
for J in '123' '456' '789'
do
for K in '!##' '$%^' '&*('
do
echo "xyz.com/param1=${I}¶m2=${J}¶m3=${K}"
done
done
done
Note that:
that '&*(' will bring you problems, since & is the character that you use to delimit each parameter.
double quotes " around echo, will make a double quote character to make this program to fail miserably
the same apply to ', \ and some others
Related
I'm trying to write a HTML parser in Lua. A major roadblock I hit almost immediately was I have no idea how to get a list of strings between 2 strings. This is important for parsing HTML, where a tag is defined by being within 2 characters (or strings of length 1), namely '<' and '>'. I am aware of this answer, but it only gets the first occurence, not all instances of a string between the 2 given strings.
What I mean by "list of strings between 2 strings" is something like this:
someFunc("<a b c> <c b a> a </c b a> </a b c>", "<", ">")
Returns:
{"a b c", "c b a", "/c b a", "/a b c"}
This does not have to parse newlines nor text in between tags, as both of those can be handled using extra logic. However, I would prefer it if it did parse newlines, so I can run the code once for the whole string returned by the first GET request.
Note: This is a experiment project to see if this is possible in the very limited Lua environment provided by the CC: Tweaked mod for Minecraft. Documentation here: https://tweaked.cc/
You can do simply:
local list = {}
local html = [[bla]]
for innerTag in html:gmatch("<(.-)>") do
list[#list] = innerTag
end
But be aware that it is weak as doesn't validade wrong things, as someone can put an < or > inside a string etc.
I am looking to change the ending of the user name based on the use case (in the language system will operate, names ends depending on how it is used).
So need to define all endings of names and define the replacement for them.
Was suggested to use .gsub regular expression to search and replace in a string:
Changing text based on the final letter of user name
"name surname".gsub(/e\b/, 'ai')
this will replace e with ai, so "name surname = namai surnamai".
How can it be used for more options like: "e = ai, us = mi, i = as" on the same record?
thanks
You can use String#gsub with block. Docs say:
In the block form, the current match string is passed in as a parameter, and variables such as $1, $2, $`, $&, and $' will be set appropriately. The value returned by the block will be substituted for the match on each call.
So you can use a regex with concatenation of all substrings to be replaced and then replace it in the block, e.g. using a hash that maps matches to replacements.
Full example:
replacements = {'e'=>'ai', 'us'=>'mi', 'i' => 'as'}
['surname', 'surnamus', 'surnami'].map do |s|
s.gsub(/(e|us|i)$/){|p| replacements[p] }
end
#Sundeep makes an important observation in a comment on the question. If, for example, the substitutions were give by the following hash:
g = {'e'=>'ai', 's'=>'es', 'us'=>'mi', 'i' => 'as'}
#=> {"e"=>"ai", "s"=>"es", "us"=>"mi", "i"=>"as"}
'surnamus' would be converted (incorrectly) to 'surnamues' merely because 's'=>'es' precedes 'us'=>'mi' in g. That situation may not exist at present, but it may be prudent to allow for it in future, particularly because it is so simple to do so:
h = g.sort_by { |k,_| -k.size }.to_h
#=> {"us"=>"mi", "e"=>"ai", "s"=>"es", "i"=>"as"}
arr = ['surname', 'surnamus', 'surnami', 'surnamo']
The substitutions can be done using the form of String##sub that employs a hash as its second argument.
r = /#{Regexp.union(h.keys)}\z/
#=> /(?-mix:us|e|s|i)\z/i
arr.map { |s| s.sub(r,h) }
#=> ["surnamai", "surnammi", "surnamas", "surnamo"]
See also Regexp::union.
Incidentally, though key-insertion order has been guaranteed for hashes since Ruby v1.9, there is a continuing debate as to whether that property should be made use of in Ruby code, mainly because there was no concept of key order when hashes were first used in computer programs. This answer provides a good example of the benefit of exploiting key order.
(Sorry for my broken English)
What I'm trying to do is matching a word (with or without numbers and special characters) or whitespace characters (whitespaces, tabs, optional new lines) in a string in Lua.
For example:
local my_string = "foo bar"
my_string:match(regex) --> should return 'foo', ' ', 'bar'
my_string = " 123!#." -- note: three whitespaces before '123!#.'
my_string:match(regex) --> should return ' ', ' ', ' ', '123!#.'
Where regex is the Lua regular expression pattern I'm asking for.
Of course I've done some research on Google, but I couldn't find anything useful. What I've got so far is [%s%S]+ and [%s+%S+] but it doesn't seem to work.
Any solution using the standart library, e.g. string.find, string.gmatch etc. is OK.
Match returns either captures or the whole match, your patterns do not define those. [%s%S]+ matches "(space or not space) multiple times more than once", basically - everything. [%s+%S+] is plain wrong, the character class [ ] is a set of single character members, it does not treat sequences of characters in any other way ("[cat]" matches "c" or "a"), nor it cares about +. The [%s+%S+] is probably "(a space or plus or not space or plus) single character"
The first example 'foo', ' ', 'bar' could be solved by:
regex="(%S+)(%s)(%S+)"
If you want a variable number of captures you are going to need the gmatch iterator:
local capt={}
for q,w,e in my_string:gmatch("(%s*)(%S+)(%s*)") do
if q and #q>0 then
table.insert(capt,q)
end
table.insert(capt,w)
if e and #e>0 then
table.insert(capt,e)
end
end
This will not however detect the leading spaces or discern between a single space and several, you'll need to add those checks to the match result processing.
Lua standard patterns are simplistic, if you are going to need more intricate matching, you might want to have a look at lua lpeg library.
Luas string.format is pretty straight forward, if you know what to format.
However, I stuck at writing a function which takes a wildcard-string to format, and a variable number of arguments to put into that blank string.
Example:
str = " %5s %3s %6s %6s",
val = {"ttyS1", "232", "9600", "230400"}
Formatting that by hand is pretty easy:
string.format( str, val[1], val[2], val[3], val[4] )
Which is the same as:
string.format(" %5s %3s %6s %6s", "ttyS1, "232", "9600","230400")
But what if I wan't to have a fifth or sixth argument?
For example:
string.format(" %1s %2s %3s %4s %5s %6s %7s %", ... )
How can I implement a string.format with an variable number of arguments?
I want to avoid appending the values one by one because of performance issues.
The application runs on embedded MCUs.
Generate arbitrary number of repeats of whatever format you want with string.rep if format is the same for all arguments. Or fill table with all formats and use table.concat. Remember that you don't need to specify index of argument in format if you don't want to reorder them.
If you just need to concatenate strings together separated by space, use more suitable tool: table.concat(table_of_strings, ' ').
You can create a table using varargs:
function foo(fmt, ...)
local t = {...}
return t[6] -- might be nil
end
Ps, don't use # on the table if you expect the argument list might contain nil. Instead use select("#", ...).
Is there anything better than string.scan(/(\w|-)+/).size (the - is so, e.g., "one-way street" counts as 2 words instead of 3)?
string.split.size
Edited to explain multiple spaces
From the Ruby String Documentation page
split(pattern=$;, [limit]) → anArray
Divides str into substrings based on a delimiter, returning an array
of these substrings.
If pattern is a String, then its contents are used as the delimiter
when splitting str. If pattern is a single space, str is split on
whitespace, with leading whitespace and runs of contiguous whitespace
characters ignored.
If pattern is a Regexp, str is divided where the pattern matches.
Whenever the pattern matches a zero-length string, str is split into
individual characters. If pattern contains groups, the respective
matches will be returned in the array as well.
If pattern is omitted, the value of $; is used. If $; is nil (which is
the default), str is split on whitespace as if ' ' were specified.
If the limit parameter is omitted, trailing null fields are
suppressed. If limit is a positive number, at most that number of
fields will be returned (if limit is 1, the entire string is returned
as the only entry in an array). If negative, there is no limit to the
number of fields returned, and trailing null fields are not
suppressed.
" now's the time".split #=> ["now's", "the", "time"]
While that is the current version of ruby as of this edit, I learned on 1.7 (IIRC), where that also worked. I just tested it on 1.8.3.
I know this is an old question, but this might be useful to someone else looking for something more sophisticated than string.split. I wrote the words_counted gem to solve this particular problem, since defining words is pretty tricky.
The gem lets you define your own custom criteria, or use the out of the box regexp, which is pretty handy for most use cases. You can pre-filter words with a variety of options, including a string, lambda, array, or another regexp.
counter = WordsCounted::Counter.new("Hello, Renée! 123")
counter.word_count #=> 2
counter.words #=> ["Hello", "Renée"]
# filter the word "hello"
counter = WordsCounted::Counter.new("Hello, Renée!", reject: "Hello")
counter.word_count #=> 1
counter.words #=> ["Renée"]
# Count numbers only
counter = WordsCounted::Counter.new("Hello, Renée! 123", rexexp: /[0-9]/)
counter.word_count #=> 1
counter.words #=> ["123"]
The gem provides a bunch more useful methods.
If the 'word' in this case can be described as an alphanumeric sequence which can include '-' then the following solution may be appropriate (assuming that everything that doesn't match the 'word' pattern is a separator):
>> 'one-way street'.split(/[^-a-zA-Z]/).size
=> 2
>> 'one-way street'.split(/[^-a-zA-Z]/).each { |m| puts m }
one-way
street
=> ["one-way", "street"]
However, there are some other symbols that can be included in the regex - for example, ' to support the words like "it's".
This is pretty simplistic but does the job if you are typing words with spaces in between. It ends up counting numbers as well but I'm sure you could edit the code to not count numbers.
puts "enter a sentence to find its word length: "
word = gets
word = word.chomp
splits = word.split(" ")
target = splits.length.to_s
puts "your sentence is " + target + " words long"
The best way to do is to use split method.
split divides a string into sub-strings based on a delimiter, returning an array of the sub-strings.
split takes two parameters, namely; pattern and limit.
pattern is the delimiter over which the string is to be split into an array.
limit specifies the number of elements in the resulting array.
For more details, refer to Ruby Documentation: Ruby String documentation
str = "This is a string"
str.split(' ').size
#output: 4
The above code splits the string wherever it finds a space and hence it give the number of words in the string which is indirectly the size of the array.
The above solution is wrong, consider the following:
"one-way street"
You will get
["one-way","", "street"]
Use
'one-way street'.gsub(/[^-a-zA-Z]/, ' ').split.size
This splits words only on ASCII whitespace chars:
p " some word\nother\tword|word".strip.split(/\s+/).size #=> 4