I'm trying to parse a text, and based on tags to do actions.
The text is:
<window>
<caption>My window
</window>
<panel>
<label>
<caption>
<position>50,50
<color>255,255,255
</label>
</panel>
Code:
function parse_tag(chunck)
for start_tag,tag_name in string.gfind(chunck,"(<(.-)>)") do
if (child_obj[tag_name]) then
print(start_tag)
for data,end_tag in string.gfind(chunck,"<" .. tag_name ..">(.-)(</" .. tag_name ..">)") do
for object_prop,value in string.gfind(data,"<(.-)>(.-)") do
print("setting property = \"" .. object_prop .. "\", value of" .. value);
end
end
print("</" .. tag_name ..">");
elseif(findInArray(main_obj,tag_name)) then
print("Invalid data");
stop();
end
end
end
for key,tag in ipairs(main_obj) do
for start_tag,tag_name,chunck,end_tag in string.gfind(data,"(<(" .. tag.name .. ")>)(.-)(</" .. tag.name .. ">)") do --> searching for window/panel start and end tags
if (findInArray(main_obj,tag_name)) then
print(start_tag)
parse_tag(chunck); --> parses the tag with child tag
print(end_tag)
end
end
end
It seems to fail getting the value, as I get the following output:
<window>
</window>
<panel>
<label>
setting property = "caption", value of
setting property = "position", value of
setting property = "color", value of
</label>
</panel>
How can I use match the string after the first <%tag%> until the next <%tag%> or end of the chunk.
string.gfind(data,"<(.-)>(.-)")
Here, you try to match the value with .-. However, - is lazy, i.e, .- will try to match as little as possible, in this case, an empty string.
Try telling it to match until the next <:
string.gfind(data,"<(.-)>(._)<")
Tried different type of captures.
This
string.gfind(data,"<(.-)>([^%<+.-%>+]+)")
Seems to work
Related
Suppose I have a variable like
foo = "/this/is a/path/my file.gif"
bar = "/this/is a/path/my file"
I want to say that if string does not end with .gif then add .gif to the end of the string.
How can i do that?
Appending .gif is trivial (s = s .. ".gif"). The remaining question is how to check whether the string ends with .gif. There are two ways to go about this: Either use string.sub
if not gif_path:find"%.gif$" then gif_path = gif_path .. ".gif" end
or pattern matching (string.find or string.match):
if gif_path:sub(-#".gif") ~= ".gif" then gif_path = gif_path .. ".gif" end
if you end up with many "ends with" checks, you should write your own string "ends with" function.
The solution is:
gif_path = "/this/is a/path/my file.gif"
if(gif_path:sub(-string.len(".gif")) ~= ".gif")
then
gif_path = gif_path .. ".gif"
end
I try to write to an string something like this:
arr << "Icd3code.create!({:text => '#{variable1}'})" + "\n"
My problem is that variable 1 is an string, that contains an ' :
variable1 = "Ami's house"
So that at the end the ouput of my code is this:
Icd3code.create!({:text => 'Ami's house'})
How you can see now i have one ' to much! I dont know what i can do to avoid this problem! Thanks
If I've understood, you want to loop over some input, building up a list of parameters, which you plan to later use to create some records. If that's the case, I think you're better off using hashes, instead of strings:
# Let's pretend this came from the big, bad, world
inputs = ["Ami's house", "Fred's house", "Jim's house"]
creation_params = []
inputs.each do |input|
creation_params << {:text => input}
end
Then you could create all the Icd3codes, like this:
creation_params.each do |params|
Icd3code.create!(params)
end
Or you could save them in a text file, for later:
File.open('dest', 'w') do |f|
f.write(creation_params.to_json)
end
variable1 = "Ami's house"
puts %Q[Icd3code.create!({:text => "#{variable1}"})] + "\n"
--output:--
Icd3code.create!({:text => "Ami's house"})
I try to get a function for setting < b > around catched strings (case insensitive), like this :
bold_string("Hello everyone","o")
> "Hell<b>o</b> every<b>o</b>ne"
bold_string("HEllo evEryonE", "e")
> "H<b>E</b>llo <b>e</b>v<b>E</b>ryon<b>E<b/>"
Now, my function looks like that :
def bold_string(str, search)
str.gsub(/(#{search})/i, '<b>\1</b>')
end
It works perfectly with the previous examples, but not with the words having some accents. There are the results I expect :
bold_string("Petite bête", "e")
> "P<b>e</b>tit<b>e</b> b<b>ê</b>t<b>e</b>"
bold_string("Petite bête", "ê")
> "P<b>e</b>tit<b>e</b> b<b>ê</b>t<b>e</b>"
In other words, I have to find a regex like /search/i, it says "you have to find the word 'search' or the word 'search' with some accents".
edit :
I see I was too simplist with my example... It should works with string and not simply chars :
bold_string("Petite bête", "êt")
> "P<b>et</b>ite</b> b<b>êt</b>e"
Regards
Pierre
edit2 :
I used the solution of F.J with this new function
def regex_from_string_including_accents(str)
accents = ['aàâ', 'eéèêë', 'oöô' 'iî']
return str.gsub(/./) do |letter|
accent_group = accents.detect{|group| group.include?(letter)}
accent_group ? "[#{accent_group}]" : letter
end
end
You could do something like the following:
def bold_string(str, search)
h = { "e" => "[eéê]", "a" => "[aáâ]" }
regex = search.gsub(/./) {|s| h.fetch(s, s)}
str.gsub(/(#{regex})/i, '<b>\1</b>')
end
Obviously this just shows you how to get started, you will need to fill h with additional accented versions of characters.
Example: http://ideone.com/KukiKc
I´m trying to do this without success:
<g:textField title="${title}" ${disabled} />
I want to apply a disabled attribute, ONLY if the ${disabled} variable is TRUE.
I don't want to use conditionals, because in other views I got a lot of code and using IF statements, will be a chaos.
The other thing is applying the attribute like this:
<g:textField title="${title}" disabled="${disabled}" />
But when I put the disabled attribute, no mather the content of the variable, It just always disables the field.
if you don't like gotomanners' solution (which seems perfectly valid to me)
<g:textField title="${title}" ${(disabled)?"disabled":""} />
your ${disabled} variable should be returning "disabled" not TRUE for that to work.
EDIT
I tried this out and saw the problem with it always being disabled no matter the value. Apparently the mere presence of the disabled keyword disables the field and the value assigned to that keyword is only a dummy value.
Anyway, Here's a fix.
Create a Taglib class(if you don't have one already)
define your own textfield tag as such...
def myTextField = { attrs, body ->
def title = attrs.remove("title")
def isDisabled = attrs.remove("disabled")
if ("true".equals(isDisabled)) {
out << """<input title="${title}" disabled="${isDisabled}" """
attrs.each { k,v ->
out << k << "=\"" << v << "\" "
}
out << "/>"
} else {
out << """<input title="${title}" """
attrs.each { k,v ->
out << k << "=\"" << v << "\" "
}
out << "/>"
}
}
in your gsp, call your textfield tag like so
<g:myTextField title="${title}" disabled="${disabled}" />
adding extra attributes like so is also valid
<g:myTextField class="title" name="theName" value="theValue" title="${title}" disabled="${disabled}" />
make sure your ${disabled} variable returns "true" or "false" as strings this time.
So I found myself needing to remove <br /> tags from the beginning and end of strings in a project I'm working on. I made a quick little method that does what I need it to do but I'm not convinced it's the best way to go about doing this sort of thing. I suspect there's probably a handy regular expression I can use to do it in only a couple of lines. Here's what I got:
def remove_breaks(text)
if text != nil and text != ""
text.strip!
index = text.rindex("<br />")
while index != nil and index == text.length - 6
text = text[0, text.length - 6]
text.strip!
index = text.rindex("<br />")
end
text.strip!
index = text.index("<br />")
while index != nil and index == 0
text = test[6, text.length]
text.strip!
index = text.index("<br />")
end
end
return text
end
Now the "<br />" could really be anything, and it'd probably be more useful to make a general use function that takes as an argument the string that needs to be stripped from the beginning and end.
I'm open to any suggestions on how to make this cleaner because this just seems like it can be improved.
gsub can take a regular expression:
text.gsub!(/(<br \/>\s*)*$/, '')
text.gsub!(/^(\s*<br \/>)*/, '')
text.strip!
class String
def strip_this!(t)
# Removes leading and trailing occurrences of t
# from the string, plus surrounding whitespace.
t = Regexp.escape(t)
sub!(/^(\s* #{t} \s*)+ /x, '')
sub!(/ (\s* #{t} \s*)+ $/x, '')
end
end
# For example.
str = ' <br /> <br /><br /> foo bar <br /> <br /> '
str.strip_this!('<br />')
p str # => 'foo bar'
You can use chomp! and slice! methods. See:
http://ruby-doc.org/core-1.8.7/String.html
def remove_breaks(text)
text.gsub((%r{^\s*<br />|<br />\s*$}, '')
end
%r{...} is another way to specify a regular expression. The advantage of %r is that you can pick your own delimeter. Using {} for the delimiters means not having to escape the /'s.
use replace method instead
str.replace("<br/>", "")