table dd
dd:([]a:("account=abcde;cash=123";"account=abc;cash=345");1 2)
result:
"account=abcde;cash=123" 1
"account=abc;cash=345" 2
I want to replace everything in account:
so the result should be
"replace;cash=123" 1
"replace;cash=345" 2
I tried this
update ssr[;"account=* ;";""] each a from dd
but it didn't work.
Try the following:
q)update {";"sv #[s;where (s:";"vs x) like "account=*";:;enlist"newVal=123"]}each a from dd
And just to throw one more answer on the pile! If you can assume the account part you want to replace is always the first member of the ; separated list you can use the slightly simpler:
update ";"sv'#[;0;:;"replace"]each";"vs'a from dd
can't use wild card * with ssr information on http://code.kx.com/q/cookbook/regex/#regex-in-q
for integrating with regex libraries.
alternative solution to ssr:
update a:{v:(" *";";")0:x;y,/:v 0}[a;"replacestring;"] from dd where a like "account=\*"
You can also try the following if you want to explicitly use ssr:
update {ssr[first "=" vs x;"account";"replace",";",last ";" vs x]} each a from dd
a x
--------------------
"replace;cash=123" 1
"replace;cash=345" 2
Related
Let's say I have this string: "123_12345_123456"
I would like to extract everything before the second "_" (underscore)
I tried:
fn:tokenize("123_1234_12345", '_')[position() le 2]
That returns:
123
1234
What I actually want is:
123_1234
How do I achieve that?
I am using XQuery 1.0
Regular expressions are flexible and compact:
replace('123_1234_12345', '_[^_]+$', '')
Another solution that may be better readable is to a) tokenize the string, b) keep the tokens you want to preserve and c) join them again:
string-join(
tokenize('123_1234_12345', '_')[position() = 1 to 2],
'_'
)
Taking the basic idea from Michael Kay's deleted answer, it could be implemented like this:
substring($input, 1, index-of(string-to-codepoints($input), 95)[2] - 1)
Looking to convert the weekend column below from the date into the written form in KDB/Q
t:flip (`contra`weekend`PnL)!(4#`abc;("2020.01.10";"2020.02.17";"2020.03.24";"2020.03.31");-222j, 844j, 1897j, 947j)
Result should update to
2020.01.10 - Jan-10
2020.02.17 - Feb-17
2020.03.24 - Mar 24
Thanks in advance for your help
How about
q)show m:("Jan";"Feb";"Mar")
"Jan"
"Feb"
"Mar"
q)exec {" - "sv/:flip(x;"-"sv'flip(m mod["m"$"D"$x;12];x[;8 9]))}weekend from t
"2020.01.10 - Jan-10"
"2020.02.17 - Feb-17"
"2020.03.24 - Mar-24"
"2020.03.31 - Mar-31"
or if the column needs to remain in the table
q)update {" - "sv/:flip(x;"-"sv'flip(m mod["m"$"D"$x;12];x[;8 9]))}weekend from t
contra weekend PnL
---------------------------------
abc "2020.01.10 - Jan-10" -222
abc "2020.02.17 - Feb-17" 844
abc "2020.03.24 - Mar-24" 1897
abc "2020.03.31 - Mar-31" 947
When it comes to string manipulation in KDB, vs (vector from scalar) and its inverse sv (scalar from vector) are usually very useful
In the above, first create a list of possible months m (I've done 3 to start with)
Next, inside a lambda for brevity's sake, can isolate the day with indexing
Then find the correct month using a combination of casting and the built-in mod operator to index into the list of months
Use sv to join these lists with a "-" and repeat the process again to join on our initial weekend column (this time with " - ")
The following code fragement should help
monthDay:{ ("Jan"; "Feb"; "Mar"; "Apr"; "May"; "Jun"; "Jul";
"Aug"; "Sep"; "Oct"; "Nov"; "Dec")[(`mm$x)-1],'"-",'string `dd$x:"D"$x }
update weekend:(weekend,'" - ",/:monthDay weekend) from `t
Another option is to use the date parsing library available as part of Kx Developer: https://code.kx.com/developer/libraries/date-parser/#printing-dates
This lib provides a number of utilities for parsing dates & times from strings, and formatting them as strings from kdb+ datatypes
Once set up, usage is like so (first few commands are setting up the env for the libraries to work & loading them in a q session - this could also be done with \l):
jonny#kodiak ~ $ source ~/developer/config/config.profile
jonny#kodiak ~ $ export AXLIBRARIES_HOME=~/developer/
jonny#kodiak ~ $ q $AXLIBRARIES_HOME/ws/axruntimecore.q_
KDB+ 3.6 2018.12.06 Copyright (C) 1993-2018 Kx Systems
l64/ 4(16)core 7360MB jonny kodiak 127.0.1.1 EXPIRE 2020.06.04 jonathon.mcmurray#aquaq.co.uk KOD #4165225
q)t:flip (`contra`weekend`PnL)!(4#`abc;("2020.01.10";"2020.02.17";"2020.03.24";"2020.03.31");-222j, 844j, 1897j, 947j)
q)update .qdate.print["%b-%d";"D"$weekend] from t
contra weekend PnL
--------------------
abc "Jan-10" -222
abc "Feb-17" 844
abc "Mar-24" 1897
abc "Mar-31" 947
q)
Note that I had to parse the string dates in your example table to kdb+ dates with "D"$ as the qdate lib expects kdb+ date/time types.
Although I would prefer Igor's method, it may be useful for you to know that system commands can be used from q console which may offer you more flexibility in picking desired format. Can be used for example in this case:
conv:{"-"^6#4_first system"date -d ", "/" sv "." vs x}
update conv'[weekend] from t
edit:
For your exact output:
update (weekend,'" - ",/: conv'[weekend]) from t
My memo line that looks something like this:
Return: #999 100.00\NSF|Balance=$242.00. Available Balance=$50.00`
or
Return: #888 45.90\WD REST.
I need it to return everything before the | if there is one, or the whole memo line if there isn't a |. Right now I have two formulas that give everything before the | or nothing if there isn't a |
memo1: left({table.memo},instr(table.memo},"|"))
memo2: replace({#Memo1},"|"," ")
How can I configure this such that if a | is present, return #Memo2, else return {table.memo}?
If I understand correctly, just make one more formula like this:
IF instr({table.memo},"|")>0
THEN {#Memo2}
ELSE {table.memo}
This displays one formula or the other based on the presence of that vertical line character.
I would use an if statement with instr:
memo1: left({table.memo},instr(table.memo},"|"))
memo2: replace({#Memo1},"|"," ")
if instr(table.memo} > 0
left({table.memo},instr(table.memo},"|"))
else
replace({#Memo1},"|"," ")
Please try something like that. (I did not check the syntax, so please check my work.)
Example for if
i have table name as res_schedule.In that table i have field as sq_name_new1.
the values inside that field is as follows:
sq_name_new1
Gawade & Sushil & Arvind(Ramchandra Ankush Gawade,Arvind Harishchandra More,Sushil Kailas Shinde)
Arvind / Krishna / Somnath(Somnath Gopinath Londhe,Arvind Harishchandra More,Krishna Shesha Devadiga)
Deshmukh/Arvind BBS(new)(Arvind Harishchandra More,Sanjay Dnyaneshwar Deshmukh)
so After spliting it i want the result as:
Ramchandra Ankush Gawade Arvind Harishchandra More Sushil Kailas Shinde Somnath Gopinath Londhe Arvind Harishchandra More Krishna Shesha Devadiga Arvind Harishchandra More Sanjay Dnyaneshwar Deshmukh
That is it should remove the initial part from the record and split the value by storing it into one by one different row.
so for this i have used the function like :
unnest(string_to_array(substring(res_scheduledjobs.sq_name_new1,'\((().*)\)'),','))
but it is not splitting the value properly.this function did the work for the record:
Deshmukh/Arvind BBS(new)(Arvind Harishchandra More,Sanjay Dnyaneshwar Deshmukh)
as:
sq_name_new1
new)(Arvind Harishchandra More
Sanjay Dnyaneshwar Deshmukh
means it is not neglecting 'new)(' this part.
so what can i do,so that it will also neglect the 'new)(' same as it did for others.
awaiting for your response.
please suggest me some solution.i need help.
Try using
'\(([^()]*)\)[^)]*$'
instead of
'\((().*)\)'
as regexp pattern.
I have an array of strings:
dd = {'L','temp1','temp23','Reas'};
I would like to extract the numbers from the strings that contain any numbers (if that makes sense). So, the solution for this question should be 1 and 23.
How can I achieve this in matlab?
Here's part of the solution. Suppose
myString = 'temp23'
then the expression
str2double(a(isstrprop(a,'digit')))
will return
23
I haven't got the time to turn this into a function to deal with your array of strings but this should get you started.
#DennisJahruddin suggested the following completion of my answer. I haven't tested it thoroughly:
dd = {'L','temp1','temp23','Reas'};
ee = cellfun(#(a) str2double(a(isstrprop(a,'digit'))),dd);
ff = ee(~isnan(ee))