Given a string like (2 5). I want to replace multiple spaces with a semi-colon in a string (2 5) in PowerBuilder
Thanks in Advance
This can be done with a regular expression. But the support for regular expression in Powerscript is minimal, you need to use an external COM object like VBScript.RegExp to do something useful.
OLEObject re
int li_retcode
string s
string value
re = Create OLEObject
li_retcode = re.ConnectToNewObject("VBScript.RegExp")
re.Pattern = "\s\s+"
re.Global = True
s = "4 2"
value = re.Replace("4 2" , ";")
MessageBox("", value) // 4;2
re.DisconnectObject()
simply cut out each word, trim and join into a string.
string ls_key = '2 5 8 9'
string ls_new = ''
long ll_pos
do
ll_pos = Pos( ls_key, ' ')
if ll_pos > 0 then
ls_new += trim( left( ls_key, ll_pos - 1) ) + ':'
ls_key = trim( mid( ls_key, ll_pos + 1 ) )
else
ls_new += trim( ls_key )
ls_key = ''
end if
loop while ll_pos > 0
return ls_new
Related
Hello everyone.
Dim txt1 As Double = Convert.ToDouble(TextBox1.Text) / 100
Dim txt2 As Double = Convert.ToDouble(TextBox2.Text)
Dim txt3 As Double = Convert.ToDouble(TextBox3.Text)
Dim txtResult As Double = Convert.ToDouble(TextBox4.Text)
Dim result As Double = txt1 * txt2 * txt3
TextBox4.Text = result
As you can see I get my result depending on what the user types in. So I have to add a space after a certain character. Textbox14.text(0) <--- after this do I want my space. It's so that after the value is higher than 999 it should type out 1 000 and not 1000. Thank you very much for any useful help, I've truly looked everywhere, I just can't find anything.
You talking about group separator. Custom Numeric Format Strings
You can use .ToString() method and define group separator in the format.
TextBox4.Text = result.ToString("0,0.000")
Different separators will be used based on the local system's language/region settings.
You can define your custome separator manually
var cultureInfo = new System.Globalization.CultureInfo("en-US");
var numberInfo = cultureInfo.NumberFormat;
numberInfo.NumberGroupSeparator = " ";
TextBox4.Text = result.ToString("0,0.000", numberInfo)
If I get it right, you want every 3 chars a space, right ?
Like 1 000 000 ?
try this :
Dim result As String, str As String, ret As String
Dim i As Integer
Dim arr As Char()
'your text to space
result = "10000000"
'reverte so we start with the end
result = StrReverse(result)
i = 0
ret = ""
' make a char array which each char is an own array element
arr = result.Take(result.Length).ToArray
'iterate through all elements
For Each str In arr
' skip the first element .
' only add a space every 3 elements
If (i <> 0) And (i Mod 3 = 0) Then
ret = ret + " "
End If
ret = ret + str
i = i + 1
Next
' revers again the output
ret = StrReverse(ret)
MsgBox(ret)
I have a string. I need to compare 1st character of the string to a specific character. Below is the C# code.
String URL = "www.vulnuryrweb.com";
bool isValid = URL[0] == '/'
&& URL[1] != '/'
&& URL[1] != '\\';
What will be VB-Script equivalent of above code?
URL = "www.vulnuryrweb.com"
char1 = Left(URL, 1)
char2 = Mid(URL, 2, 1)
isValid = ( char1 = "/" And char2 <> "/" And char2 <> "\" )
MsgBox isValid
Update: It can be simplified with the Like operator :
URL = "www.vulnuryrweb.com"
isValid = URL Like "/[/\]*"
Debug.Print isValid
[/\] checks if the second character is / or \, and * matches 0 or more characters.
According to http://www.w3schools.com/asp/func_mid.asp you will need to do
URL = "www.vulnuryrweb.com";
firstLetter = Mid(URL,1,1)
which will return w in this case
use the Mid function to get the first n chars of a string, then compare this to the results you want to check for
Dim isValid
isValid = (Mid(URL, 1, 1) = "/" And Mid(URL, 2, 1) <> "/" And Mid(URL, 2, 1) <> "\")
Note that Mid uses a 1 based index for characters (index 1 is the first char) whereas C# uses 0 based (url[0] is the first char)
So I have the following code to split a string between whitespaces:
text = "I am 'the text'"
for string in text:gmatch("%S+") do
print(string)
end
The result:
I
am
'the
text'
But I need to do this:
I
am
the text --[[yep, without the quotes]]
How can I do this?
Edit: just to complement the question, the idea is to pass parameters from a program to another program. Here is the pull request that I am working, currently in review: https://github.com/mpv-player/mpv/pull/1619
There may be ways to do this with clever parsing, but an alternative way may be to keep track of a simple state and merge fragments based on detection of quoted fragments. Something like this may work:
local text = [[I "am" 'the text' and "some more text with '" and "escaped \" text"]]
local spat, epat, buf, quoted = [=[^(['"])]=], [=[(['"])$]=]
for str in text:gmatch("%S+") do
local squoted = str:match(spat)
local equoted = str:match(epat)
local escaped = str:match([=[(\*)['"]$]=])
if squoted and not quoted and not equoted then
buf, quoted = str, squoted
elseif buf and equoted == quoted and #escaped % 2 == 0 then
str, buf, quoted = buf .. ' ' .. str, nil, nil
elseif buf then
buf = buf .. ' ' .. str
end
if not buf then print((str:gsub(spat,""):gsub(epat,""))) end
end
if buf then print("Missing matching quote for "..buf) end
This will print:
I
am
the text
and
some more text with '
and
escaped \" text
Updated to handle mixed and escaped quotes. Updated to remove quotes. Updated to handle quoted words.
Try this:
text = [[I am 'the text' and '' here is "another text in quotes" and this is the end]]
local e = 0
while true do
local b = e+1
b = text:find("%S",b)
if b==nil then break end
if text:sub(b,b)=="'" then
e = text:find("'",b+1)
b = b+1
elseif text:sub(b,b)=='"' then
e = text:find('"',b+1)
b = b+1
else
e = text:find("%s",b+1)
end
if e==nil then e=#text+1 end
print("["..text:sub(b,e-1).."]")
end
Lua Patterns aren't powerful to handle this task properly. Here is an LPeg solution adapted from the Lua Lexer. It handles both single and double quotes.
local lpeg = require 'lpeg'
local P, S, C, Cc, Ct = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Ct
local function token(id, patt) return Ct(Cc(id) * C(patt)) end
local singleq = P "'" * ((1 - S "'\r\n\f\\") + (P '\\' * 1)) ^ 0 * "'"
local doubleq = P '"' * ((1 - S '"\r\n\f\\') + (P '\\' * 1)) ^ 0 * '"'
local white = token('whitespace', S('\r\n\f\t ')^1)
local word = token('word', (1 - S("' \r\n\f\t\""))^1)
local string = token('string', singleq + doubleq)
local tokens = Ct((string + white + word) ^ 0)
input = [["This is a string" 'another string' these are words]]
for _, tok in ipairs(lpeg.match(tokens, input)) do
if tok[1] ~= "whitespace" then
if tok[1] == "string" then
print(tok[2]:sub(2,-2)) -- cut off quotes
else
print(tok[2])
end
end
end
Output:
This is a string
another string
these
are
words
I want to convert string text to table and this text must be divided on characters. Every character must be in separate value of table, for example:
a="text"
--converting string (a) to table (b)
--show table (b)
b={'t','e','x','t'}
You could use string.gsub function
t={}
str="text"
str:gsub(".",function(c) table.insert(t,c) end)
Just index each symbol and put it at same position in table.
local str = "text"
local t = {}
for i = 1, #str do
t[i] = str:sub(i, i)
end
The builtin string library treats Lua strings as byte arrays.
An alternative that works on multibyte (Unicode) characters is the
unicode library that
originated in the Selene project.
Its main selling point is that it can be used as a drop-in replacement
for the string library, making most string operations “magically”
Unicode-capable.
If you prefer not to add third party dependencies your task can easily
be implemented using LPeg.
Here is an example splitter:
local lpeg = require "lpeg"
local C, Ct, R = lpeg.C, lpeg.Ct, lpeg.R
local lpegmatch = lpeg.match
local split_utf8 do
local utf8_x = R"\128\191"
local utf8_1 = R"\000\127"
local utf8_2 = R"\194\223" * utf8_x
local utf8_3 = R"\224\239" * utf8_x * utf8_x
local utf8_4 = R"\240\244" * utf8_x * utf8_x * utf8_x
local utf8 = utf8_1 + utf8_2 + utf8_3 + utf8_4
local split = Ct (C (utf8)^0) * -1
split_utf8 = function (str)
str = str and tostring (str)
if not str then return end
return lpegmatch (split, str)
end
end
This snippet defines the function split_utf8() that creates a table
of UTF8 characters (as Lua strings), but returns nil if the string
is not a valid UTF sequence.
You can run this test code:
tests = {
en = [[Lua (/ˈluːə/ LOO-ə, from Portuguese: lua [ˈlu.(w)ɐ] meaning moon; ]]
.. [[explicitly not "LUA"[1]) is a lightweight multi-paradigm programming ]]
.. [[language designed as a scripting language with "extensible ]]
.. [[semantics" as a primary goal.]],
ru = [[Lua ([лу́а], порт. «луна») — интерпретируемый язык программирования, ]]
.. [[разработанный подразделением Tecgraf Католического университета ]]
.. [[Рио-де-Жанейро.]],
gr = [[Η Lua είναι μια ελαφρή προστακτική γλώσσα προγραμματισμού, που ]]
.. [[σχεδιάστηκε σαν γλώσσα σεναρίων με κύριο σκοπό τη δυνατότητα ]]
.. [[επέκτασης της σημασιολογίας της.]],
XX = ">\255< invalid"
}
-------------------------------------------------------------------------------
local limit = 14
for lang, str in next, tests do
io.write "\n"
io.write (string.format ("<%s %3d> ->", lang, #str))
local chars = split_utf8 (str)
if not chars then
io.write " INVALID!"
else
io.write (string.format (" <%3d>", #chars))
for i = 1, #chars > limit and limit or #chars do
io.write (string.format (" %q", chars [i]))
end
end
end
io.write "\n"
Btw., building a table with LPeg is significantly faster than calling
table.insert() repeatedly.
Here are stats for splitting the whole of Gogol’s Dead Souls (in
Russian, 1023814 bytes raw, 571395 characters UTF) on my machine:
library method time in ms
string table.insert() 380
string t [#t + 1] = c 310
string gmatch & for loop 280
slnunicode table.insert() 220
slnunicode t [#t + 1] = c 200
slnunicode gmatch & for loop 170
lpeg Ct (C (...)) 70
You can below code to achieve this easily.
t = {}
str = "text"
for i=1, string.len(str) do
t[i]= (string.sub(str,i,i))
end
for k , v in pairs(t) do
print(k,v)
end
-- 1 t
-- 2 e
-- 3 x
-- 4 t
Using string.sub
string.sub(s, i [, j])
Return a substring of the string passed. The substring starts at i. If the third argument j is not given, the substring will end at the end of the string. If the third argument is given, the substring ends at and includes j.
I have string
'TEST1, TEST2, TEST3'
I want to have
'TEST1,TEST2,TEST3'
Is in powerbuilder is a function like replace, substr or something?
One way is to use the database since you probably have an active connection.
string ls_stringwithspaces = "String String String String"
string ls_stringwithnospace = ""
string ls_sql = "SELECT replace('" + ls_stringwithspaces + "', ' ', '')"
DECLARE db DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql USING SQLCA;
OPEN DYNAMIC db;
IF SQLCA.SQLCode > 0 THEN
// erro handling
END IF
FETCH db INTO :ls_stringwithnospace;
CLOSE db;
MessageBox("", ls_stringwithnospace)
Sure there is (you could have easily found it in the help) but it is not quite helpful, though.
Its prototype is Replace ( string1, start, n, string2 ), so you need to know the position of the string to replace before calling it.
There is a common wrapper for this that consists of looping on pos() / replace() until there is nothing left to replace. The following is the source code of a global function:
global type replaceall from function_object
end type
forward prototypes
global function string replaceall (string as_source, string as_pattern, string as_replace)
end prototypes
global function string replaceall (string as_source, string as_pattern, string as_replace);//replace all occurences of as_pattern in as_source by as_replace
string ls_target
long i, j
ls_target=""
i = 1
j = 1
do
i = pos( as_source, as_pattern, j )
if i>0 then
ls_target += mid( as_source, j, i - j )
ls_target += as_replace
j = i + len( as_pattern )
else
ls_target += mid( as_source, j )
end if
loop while i>0
return ls_target
end function
Beware that string functions (searching & concatenating) in PB are not that efficient, and an alternative solution could be to use the FastReplaceall() global function provided by the PbniRegex extension. It is a c++ compiled plugin for PB classic from versions 9 to 12.
I do that:
long space, ll_a
FOR ll_a = 1 to len(ls_string)
space = pos(ls_string, " ")
IF space > 0 THEN
ls_string= Replace(ls_string, space, 1, "")
END IF
NEXT