replace one quote symbol into two quotes in informix - informix

I am working on informix-4gl.my programs is about to adds and update user information from one tables to many tables.In case, there were information from user that contains "'" symbol or single quote such as the purchaser name or user address.My problems is when I update the tables,the information that contains single quote symbols will not updated.And now I had found that there must be an double quotes to enter the values that was in different online server.Now, I am going to change single quotes to double quotes.I had tried changing code like this but its reads only single quotes.
LET rmks_lgth = LENGTH(p_crsell.crse_purc_nme)
FOR a = 1 TO rmks_lgth
IF p_crsell.crse_purc_nme[a] = "'" THEN
LET p_crsell.crse_purc_nme[a] = "''"
END IF
END FOR
I had tried to change the codes in order to produce double quotes.the quotes must be double up for every input that contains "'" quote symbol.
LET rmks_lgth = LENGTH(p_crsell.crse_purc_nme)
FOR a = 1 TO rmks_lgth
FOR b = 1 TO rmks_lgth
IF p_crsell.crse_purc_nme[a] = "'" THEN
LET p_crsell.crse_purc_nme[a] = "'"
LET p_crsell.crse_purc_nme[b] = "'"
END IF
END FOR
END FOR
codes above will only produce output
''
where there is no other values.
someone names ceinmark had suggest that "I need create a 4GL function to found the quote , then strip the string in two at the point you found it and concat the "new" quote with this two parts of the string."

Rahim, the solution bellow is only for 4GL code , do not apply to Informix SQL Statement.
Easily this can be rewrite to Informix Stored Procedure (but I know as SP this will not solve your problem) :
MAIN
DEFINE p_sql varCHAR(200)
DEFINE p_dest varCHAR(200)
DEFINE i,x,z INTEGER
LET p_sql = arg_val(1)
LET x=1
LET p_dest=''
FOR i = 1 TO length(p_sql)
IF p_sql[i,i] = '"' THEN
LET p_dest=p_dest,p_sql[x,i],'"'
LET x=i+1
END IF
END FOR
LET i=length(p_sql)
IF x < i THEN
LET p_dest=p_dest,p_sql[x,i]
END IF
DISPLAY p_sql
DISPLAY p_dest
END MAIN
The test result:
$ fglgo x "test 'one' "
test 'one'
test 'one'
$ fglgo x 'test "one" '
test "one"
test ""one""
$ fglgo x 'test "one"'
test "one"
test ""one""
$ fglgo x 'test "one" x'
test "one" x
test ""one"" x

Related

Parsing a string in z/OS REXX with partial case-insensitivity

I have a REXX parameter string in this format:
arg = 'update summary(A summary of something) description(The description)'
and I'm parsing out the mode, summary and description as follows:
parse upper var arg mode . ,
1, 'SUMMARY('summary')' .,
1, 'DESCRIPTION('description')' .
I convert the arg to upper-case so that the SUMMARY and DESCRIPTION keywords are effectively case-insensitive (the user can code Summary or SUmmAry or sUmMaRy etc) but of course now I've just translated my actual summary and description to upper-case.
How can I make the parsing case-insensitive for the keywords, but keep the correct case for the actual parameters?
I've thought about extracting the character positions of the keywords and using them in the PARSE statement instead of '1' etc, but want a simple concise process if possible.
I came up with this 'toUpper' function, which is a bit simpler than expected. It takes a string and a list of words as input and returns the string with any of the words converted to upper case if found:
parms = 'UPdatE summary(The summary) Description(The description)'
say 'Parms are :' parms
parms = toUpper(parms, 'CHANGE UPDATE SUMMARY DESCRIPTION')
say 'Parms are now :' parms
exit
/********************************************************************/
/* Subroutines */
/********************************************************************/
toUpper:
parse arg string, wordList
stringUpper = string
upper stringUpper wordlist
do i = 1 to words(wordlist)
word = word(wordlist,i)
pos = pos(word, stringUpper)
if pos > 0 then string = overlay(word, string, pos)
end
return string
Output:
Parms are : UPdatE summary(The summary) Description(The description)
Parms are now : UPDATE SUMMARY(The summary) DESCRIPTION(The description)
This is a pretty common task when trying to simulate TSO-ish / IDCAMS-ish syntax in Rexx. I usually do something like this. It's such a short idiom, I never bother to make a subroutine out of it, just use it inline.
summary = 'Whatever the default value is'
description = 'Whatever the default value is'
parse var arg mode arg
mode = upper(mode)
do while arg <> ''
parse var arg keyword '(' value ')' arg
select upper(keyword)
when 'SUMMARY' then summary = value
when 'DESCRIPTION' then description = value
otherwise Say 'Unknown option:' keyword
end
end
As supplied Ross's code won't work on a z/OS system. The REXX on z/OS is a bit ancient. :-( The following codes will work.
summary = 'Whatever the default value is'
description = 'Whatever the default value is'
arg = 'UPdatE summary(The summary) Description(The description)'
parse var arg mode arg
upper mode
do while arg <> ''
parse var arg keyword '(' value ')' arg
upper keyword
select
when keyword='SUMMARY' then summary = value
when keyword='DESCRIPTION' then description = value
otherwise Say 'Unknown option:' keyword
end
end

Creating a Cipher Code in Ruby

I'm tasked with creating a Caesar cipher for a project I am working on. A Caesar cipher takes each letter in a string of text and replaces it with a letter a fixed number of places away from it (dictated by the cipher key). For instance if my text is "cat" and my cipher key is 3, my new word would be "fdw" (I'm assuming positive numbers move the letters to the right). I've been able to get my code to solve correctly for most strings of text, but I am finding that if my string includes > ? or # it will not work. Their ASCii codes are 62,63 and 64 if that helps. Any input is appreciated!
def caesar_cipher(str, num)
strArray = str.split('')
cipherArray = strArray.collect do |letter|
letter = letter.ord
if (65...90).include?(letter + num) || (97...122).include?(letter + num)
letter = letter + num
elsif (91...96).include?(letter + num) || (123...148).include?(letter + num)
letter = (letter - 26) + num
else
letter
end
end
cipherArray = cipherArray.collect {|x| x.chr}
cipher = cipherArray.join('')
end
caesar_cipher("Am I ill-prepared for this challenge?", 3)
#ord 62-64 DON'T work >, ?, #
You should create an alphabet variable, just think in if you use both ends then you will have 2 problems: negative numbers and an ASCii number that doesn't exist. You can handle this with module operator % or with a single subtraction.
alphabet = "abcde"
text_to_cipher= "aaee" => 0044 #number based in his position at aphabet var
key = 3
result will be 3377 => dd¡? or any other symbol since 7 is out of the string length "abcde" same happens with ASCii at its ends.
With module operator, you can restrict that.
size_of_your_alphabet = 5 # For this case
7%size_of_your_alphabet = 2
The Ruby builtin tr is ideal to implement substitution ciphers.
Step 1: assemble the characters you wish to transform.
chars = ["A".."Z", "a".."z", ">".."#"].flat_map(&:to_a)
Step 2: create a 1:1 array of the transformed characters
transformed = chars.map{|c| (c.ord + 3).chr}
Step 3: apply tr to transform the string.
str.tr(chars.join, transformed.join)
Full working example:
def caesar_cipher(str, num)
chars = ["A".."Z", "a".."z", ">".."#"].flat_map(&:to_a)
transformed = chars.map{|c| (c.ord + num).chr}
str.tr(chars.join, transformed.join)
end
Output:
> caesar_cipher("Am I ill-prepared for this challenge?", 3)
#=> "Dq L mpp-tvitevih jsv xlmw gleppirkiC"
Notes:
Most substitution ciphers actually rely on letter rotation, not ASCII values. My inital assumption was that you wanted a rotation, e.g. ("a".."z").to_a.rotate(num). See prior edit for a working example of that.
You can use ranges in tr() to create a really simple Caesar cipher: str.tr('A-Za-z','B-ZAb-za')
Edit: Also, because of the range specification feature, the \ is an escape character so that you can use literals like -. See this SO answer for details. I think the above exhibits a bug due to this, because it contains a \ which should be escaped by another \.

Lua: Quoted arguments passed as one in function

I'm attempting to simplify a script, and my attempts are failing. I'm making a function that will pass the given arguments and turn them into an indexed table, but I want to be able to pass quoted and non-quoted alike and have the function recognize that quoted arguments are considered one value while also respecting non-quoted arguments.
For example:
makelist dog "brown mouse" cat tiger "colorful parrot"
should return an indexed table like the following:
list_table = {"dog", "brown mouse", "cat", "tiger", "colorful parrot"}
The code I have works for quoted, but it's messing up on the non-quoted, and on top of that, adds the quoted arguments a second time. Here's what I have:
function makelist(str)
require 'tprint'
local list_table = {}
for word in string.gmatch(str, '%b""') do
table.insert(list_table, word)
end
for word in string.gmatch(str, '[^%p](%a+)[^%p]') do
table.insert(list_table, word)
end
tprint(list_table)
end
I'm not understanding why the omission of quotes is being ignored, and also is chopping off the first letter. That is, this is the output I receive from tprint (a function that prints a table out, not relevant to the code):
makelist('dog "brown mouse" cat tiger "colorful parrot"')
1=""brown mouse""
2=""colorful parrot""
3="og"
4="rown"
5="mouse"
6="cat"
7="tiger"
8="olorful"
9="parrot"
As you can see, 'd', 'b', and 'c' are missing. What fixes do I need to make so that I can get the following output instead?
1="brown mouse"
2="colorful parrot"
3="dog"
4="cat"
5="tiger"
Or better yet, have them retain the same order they were dictated as arguments, if that's possible at all.
local function makelist(str)
local t = {}
for quoted, non_quoted in ('""'..str):gmatch'(%b"")([^"]*)' do
table.insert(t, quoted ~= '""' and quoted:sub(2,-2) or nil)
for word in non_quoted:gmatch'%S+' do
table.insert(t, word)
end
end
return t
end
It may be easier to simply split on whitespaces and concatenate those elements that are inside quotes. Something like this may work (I added few more test cases):
function makelist(str)
local params, quoted = {}, false
for sep, word in str:gmatch("(%s*)(%S+)") do
local word, oquote = word:gsub('^"', "") -- check opening quote
local word, cquote = word:gsub('"$', "") -- check closing quote
-- flip open/close quotes when inside quoted string
if quoted then -- if already quoted, then concatenate
params[#params] = params[#params]..sep..word
else -- otherwise, add a new element to the list
params[#params+1] = word
end
if quoted and word == "" then oquote, cquote = 0, oquote end
quoted = (quoted or (oquote > 0)) and not (cquote > 0)
end
return params
end
local list = makelist([[
dog "brown mouse" cat tiger " colorful parrot " "quoted"
in"quoted "terminated by space " " space started" next "unbalanced
]])
for k, v in ipairs(list) do print(k, v) end
This prints the following list for me:
1 dog
2 brown mouse
3 cat
4 tiger
5 colorful parrot
6 quoted
7 in"quoted
8 terminated by space
9 space started
10 next
11 unbalanced
First thanks for your question, got me to learn the basics of Lua!
Second, so I think you went with your solution in a bit of misdirection. Looking at the question I just said why don't you split once by the quotes (") and than choose where you want to split by space.
This is what I came up with:
function makelist(str)
local list_table = {}
i=0
in_quotes = 1
if str:sub(0,1) == '"' then
in_quotes = 0
end
for section in string.gmatch(str, '[^"]+') do
i = i + 1
if (i % 2) == in_quotes then
for word in string.gmatch(section, '[^ ]+') do
table.insert(list_table, word)
end
else
table.insert(list_table, section)
end
end
for key,value in pairs(list_table) do print(key,value) end
end
The result:
1 dog
2 brown mouse
3 cat
4 tiger
5 colorful parrot

Spirit: Allowing a character at the begining but not in the middle

I'm triying to write a parser for javascript identifiers so far this is what I have:
// All this rules have string as attribute.
identifier_ = identifier_start
>>
*(
identifier_part >> -(qi::char_(".") > identifier_part)
)
;
identifier_part = +(qi::alnum | qi::char_("_"));
identifier_start = qi::char_("a-zA-Z$_");
This parser work fine for the list of "good identifiers" in my tests:
"x__",
"__xyz",
"_",
"$",
"foo4_.bar_3",
"$foo.bar",
"$foo",
"_foo_bar.foo",
"_foo____bar.foo"
but I'm having trouble with one of the bad identifiers: foo$bar. This is supposed to fail, but it success!! And the sintetized attribute has the value "foo".
Here is the debug ouput for foo$bar:
<identifier_>
<try>foo$bar</try>
<identifier_start>
<try>foo$bar</try>
<success>oo$bar</success>
<attributes>[[f]]</attributes>
</identifier_start>
<identifier_part>
<try>oo$bar</try>
<success>$bar</success>
<attributes>[[f, o, o]]</attributes>
</identifier_part>
<identifier_part>
<try>$bar</try>
<fail/>
</identifier_part>
<success>$bar</success>
<attributes>[[f, o, o]]</attributes>
</identifier_>
What I want is to the parser fails when parsing foo$bar but not when parsing $foobar.
What I'm missing?
You don't require that the parser needs to consume all input.
When a rule stops matching before the $ sign, it returns with success, because nothing says it can't be followed by a $ sign. So, you would like to assert that it isn't followed by a character that could be part of an identifier:
identifier_ = identifier_start
>>
*(
identifier_part >> -(qi::char_(".") > identifier_part)
) >> !identifier_start
;
A related directive is distinct from the Qi repository: http://www.boost.org/doc/libs/1_55_0/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html

Regular expression to remove only beginning and end html tags from string?

I would like to remove for example <div><p> and </p></div> from the string below. The regex should be able to remove an arbitrary number of tags from the beginning and end of the string.
<div><p>text to <span class="test">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>
I have been tinkering with rubular.com without success. Thanks!
def remove_html_end_tags(html_str)
html_str.match(/\<(.+)\>(?!\W*\<)(.+)\<\/\1\>/m)[2]
end
I'm not seeing the problem of \<(.+)> consuming multiple opening tags that Alan Moore pointed out below, which is odd because I agree it's incorrect. It should be changed to \<([^>\<]+)> or something similar to disambiguate.
def remove_html_end_tags(html_str)
html_str.match(/\<([^\>\<]+)\>(?!\W*?\<)(.+)\<\/\1\>/m)[2]
end
The idea is that you want to capture everything between the open/close of the first tag encountered that is not followed immediately by another tag, even with spaces between.
Since I wasn't sure how (with positive lookahead) to say give me the first key whose closing angle bracket is followed by at least one word character before the next opening angle bracket, I said
\>(?!\W*\<)
find the closing angle bracket that does not have all non-word characters before the next open angle bracket.
Once you've identified the key with that attribute, find its closing mate and return the stuff between.
Here's another approach. Find tags scanning forward and remove the first n. Would blow up with nested tags of the same type, but I wouldn't take this approach for any real work.
def remove_first_n_html_tags(html_str, skip_count=0)
matches = []
tags = html_str.scan(/\<([\w\s\_\-\d\"\'\=]+)\>/).flatten
tags.each do |tag|
close_tag = "\/%s" % tag.split(/\s+/).first
match_str = "<#{tag}>(.+)<#{close_tag}>"
match = html_str.match(/#{match_str}/m)
matches << match if match
end
matches[skip_count]
end
Still involves some programming:
str = '<div><p>text to <span class="test">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>'
while (m = /\A<.+?>/.match(str)) && str.end_with?('</' + m[0][1..-1])
str = str[m[0].size..-(m[0].size + 2)]
end
Cthulhu you out there?
I am going to go ahead and answer my own question. Below is the programmatic route:
The input string goes into the first loop as an array in order to remove the front tags. The resulting string is looped through in reverse order in order to remove the end tags. The string is then reversed in order to put it in the correct order.
def remove_html_end_tags(html_str)
str_no_start_tag = ''
str_no_start_and_end_tag = ''
a = html_str.split("")
i= 0
is_text = false
while i <= (a.length - 1)
if (a[i] == '<') && !is_text
while (a[i] != '>')
i+= 1
end
i+=1
else
is_text = true
str_no_start_tag << a[i]
i+=1
end
end
a = str_no_start_tag.split("")
i= a.length - 1
is_text = false
while i >= 0
if (a[i] == '>') && !is_text
while (a[i] != '<')
i-= 1
end
i-=1
else
is_text = true
str_no_start_and_end_tag << a[i]
i-=1
end
end
str_no_start_and_end_tag.reverse!
end
(?:\<div.*?\>\<p.*?\>)|(?:\<\/p\>\<\/div\>) is the expression you need. But this doesn't check for every scenario... if you are trying to parse any possible combination of tags, you may want to look at other ways to parse.
Like for example, this expression doesn't allow for any whitespace between the div and p tag. So if you wanted to allow for that, you would add \s* inbetween the \>\< sections of the tag like so: (?:\<div.*?\>\s*\<p.*?\>)|(?:\<\/p\>\s*\<\/div\>).
The div tag and the p tag are expected to be lowercase, as the expression is written. So you may want to figure out a way to check for upper or lower case letters for each, so that Div or dIV would be found too.
Use gskinner's RegEx tool for testing and learning Regular Expressions.
So your end ruby code should look something like this:
# Ruby sample for showing the use of regular expressions
str = "<div><p>text to <span class=\"test\">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>"
puts 'Before Reguar Expression: "', str, '"'
str.gsub!(/(?:\<div.*?\>\s*\<p.*?\>)|(?:\<\/p\>\s*\<\/div\>)/, "")
puts 'After Regular Expression', str
system("pause")
EDIT: Replaced div*? to div.*? and replaced p*? to p.*? per suggestions in the comments.
EDIT: This answer doesn't allow for any set of tags, just the two listed in the first line of the question.

Resources