How to convert hexBinary (MsgId) to character in esql? - ibm-mq

I'm trying to put MQMD.MsgId to XMLNSC.MsgId field, like this:
SET OutputRoot.XMLNSC.Root.MsgId = InputRoot.MQMD.MsgId;
But I'm getting X'414d51204d39392e5352442e4330302e56c47bd4203b3708' instead of just 414d51204d39392e5352442e4330302e56c47bd4203b3708.
Also i've tried to cast MsgId to CHARACTER, but result is the same.
How to get rid of quotes and 'X'?

I don't have enough reputation to 'add a commment' yet, but working with so many languages, I've learned to dislike SUBSTRING and LENGTH type functions. In the case of answer 'Feb 28 2016 at 10:41' above (yes I found this answer in response to my own search - for the "CAST(InputRoot.MQMD.MsgId AS CHAR)" above, I chose to use this instead:
DECLARE MsgId CHAR RIGHT(LEFT(CAST(InputRoot.MQMD.MsgId AS CHAR),50),48);
This assumes MsgId is always 24 hex pairs long (24x2=48) and goes for LEFT 50 first (taking off the last single quote), then RIGHT 48 (taking off the first X char and the first single quote). Does anyone disagree with the assumption? It also has the bonus of condensing to one line as it's not necessary to have two references to "MsgId" in 'SUBSTRING'

You could try something like this:
DECLARE msgId CHARACTER CAST(InputRoot.MQMD.MsgId AS CHARACTER);
SET OutputRoot.XMLNSC.Root.MsgId = SUBSTRING(msgId FROM 3 FOR LENGTH(msgId) - 3);

With ESQL SUBSTRING you can also use BEFORE and AFTER
DECLARE MsgIdAsChar CHAR SUBSTRING(SUBSTRING(CAST(InputRoot.MQMD.MsgId AS CHAR) AFTER '''') BEFORE '''');
BEFORE and AFTER are also extremely handy when it comes to looking for things in strings.
DECLARE TheHaystack CHAR ‘Where a value is 99 out of a maximum value of 100);
DECLARE TheValue CHAR SUBSTRING(SUBSTRING(TheHaystack AFTER 'value is ') BEFORE ' ');

Related

Format string in Oracle

I'm building a string in oracle, where I get a number from a column and make it a 12 digit number with the LPad function, so the length of it is 12 now.
Example: LPad(nProjectNr,12,'0') and I get 000123856812 (for example).
Now I want to split this string in parts of 3 digit with a "\" as prefix, so that the result will look like this \000\123\856\812.
How can I archive this in a select statement, what function can accomplish this?
Assuming strings of 12 digits, regexp_replace could be a way:
select regexp_replace('000123856812', '(.{3})', '\\\1') from dual
The regexp matches sequences of 3 characters and adds a \ as a prefix
It is much easier to do this using TO_CHAR(number) with the proper format model. Suppose we use \ as the thousands separator.... (alas we can't start a format model with a thousands separator - not allowed in TO_CHAR - so we still need to concatenate a \ to the left):
See also edit below
select 123856812 as n,
'\' || to_char(123856812, 'FM000G000G000G000', 'nls_numeric_characters=.\') as str
from dual
;
N STR
--------- ----------------
123856812 \000\123\856\812
Without the FM format model modifier, TO_CHAR will add a leading space (placeholder for the sign, plus or minus). FM means "shortest possible string representation consistent with the model provided" - that is, in this case, no leading space.
Edit - it just crossed my mind that we can exploit TO_CHAR() even further and not need to concatenate the first \. The thousands separator, G, may not be the first character of the string, but the currency symbol, placeholder L, can!
select 123856812 as n,
to_char(123856812, 'FML000G000G000G000',
'nls_numeric_characters=.\, nls_currency=\') as str
from dual
;
SUBSTR returns a substring of a string passed as the first argument. You can specify where the substring starts and how many characters it should be.
Try
SELECT '\'||SUBSTR('000123856812', 1,3)||'\'||SUBSTR('000123856812', 4,3)||'\'||SUBSTR('000123856812', 7,3)||'\'||SUBSTR('000123856812', 10,3) FROM dual;

How to parse data in RPG

I have an order number which is character 10 positions.
I would like to know where the leading blanks end. Only blanks.
So if the number is
' 012345' I want 012345 - Can I do this in RPG? I have tried some FREE codes
but have trouble getting to work in general. So I prefer the old way
or Free is ok if we must.
So what i need to know is, how many positions of the 10 position field are having data? so if the data is 012345 this means 6 positions are filled and 4 are blanks.
Use %scan to locate the blank.
dcl-s source char(10) inz('12345');
dcl-s pos zoned(5);
pos = %scan(' ':source) - 1;
*inlr = *on;
After the eval pos = 5.
If you want to deal with the value without leading blanks, you can use %trim or %trimL. The former will trim spaces from the front and end. The latter will only trim spaces from the front (left).
newOrder = %trimL( originalOrder );
Although your example is a bit odd. Either you typo'd what you want (two 3's?) or if you really do want to insert a 3, then that would require more work. Let me know.
Edit: Maybe this logic better answers what you're looking to do.
To count the number of non-blanks, you can do this:
valueCount = %len( %trim( originalOrder ) );
And if you need to know the number of blanks instead, it's simply:
blankCount = %len( originalOrder ) - %len( %trim( originalOrder ) );
I hope that answers your question.
You can use XLATE to replace all blanks in your string with zeros

In TI-BASIC, how do I add a variable in the middle of a String?

I am wondering how to make something where if X=5 and Y=2, then have it output something like
Hello 2 World 5.
In Java I would do
String a = "Hello " + Y + " World " + X;
System.out.println(a);
So how would I do that in TI-BASIC?
You have two issues to work out, concatenating strings and converting integers to a string representation.
String concatenation is very straightforward and utilizes the + operator. In your example:
"Hello " + "World"
Will yield the string "Hello World'.
Converting numbers to strings is not as easy in TI-BASIC, but a method for doing so compatible with the TI-83+/84+ series is available here. The following code and explanation are quoted from the linked page:
:"?
:For(X,1,1+log(N
:sub("0123456789",ipart(10fpart(N10^(-X)))+1,1)+Ans
:End
:sub(Ans,1,length(Ans)-1?Str1
With our number stored in N, we loop through each digit of N and store
the numeric character to our string that is at the matching position
in our substring. You access the individual digit in the number by
using iPart(10fPart(A/10^(X, and then locate where it is in the string
"0123456789". The reason you need to add 1 is so that it works with
the 0 digit.
In order to construct a string with all of the digits of the number, we first create a dummy string. This is what the "? is used
for. Each time through the For( loop, we concatenate the string from
before (which is still stored in the Ans variable) to the next numeric
character that is found in N. Using Ans allows us to not have to use
another string variable, since Ans can act like a string and it gets
updated accordingly, and Ans is also faster than a string variable.
By the time we are done with the For( loop, all of our numeric characters are put together in Ans. However, because we stored a dummy
character to the string initially, we now need to remove it, which we
do by getting the substring from the first character to the second to
last character of the string. Finally, we store the string to a more
permanent variable (in this case, Str1) for future use.
Once converted to a string, you can simply use the + operator to concatenate your string literals with the converted number strings.
You should also take a look at a similar Stack Overflow question which addresses a similar issue.
For this issue you can use the toString( function which was introduced in version 5.2.0. This function translates a number to a string which you can use to display numbers and strings together easily. It would end up like this:
Disp "Hello "+toString(Y)+" World "+toString(X)
If you know the length of "Hello" and "World," then you can simply use Output() because Disp creates a new line after every statement.

How to count the number of space-delimited substrings in a string

Dim str as String
str = "30 40 50 60"
I want to count the number of substrings.
Expected Output: 4
(because there are 4 total values: 30, 40, 50, 60)
How can I accomplish this in VB6?
You could try this:
arrStr = Split(str, " ")
strCnt = UBound(arrStr) + 1
msgBox strCnt
Of course, if you've got Option Explicit set (which you should..) then declare the variables above first..
Your request doesn't make any sense. A string is a sequence of text. The fact that that sequence of text contains numbers separated by spaces is quite irrelevant. Your string looks like this:
30 40 50 60
There are not 4 separate values, there is only one value, shown above—a single string.
You could also view the string as containing 11 individual characters, so it could be argued that the "count" of the string would be 11, but this doesn't get you any further towards your goal.
In order to get the result that you expect, you need to split the string into multiple strings at each space, producing 4 separate strings, each containing a 2-digit numeric value.
Of course, the real question is why you're storing this value in a string in the first place. If they're numeric values, you should store them in an array (for example, an array of Integers). Then you can easily obtain the number of elements in the array using the LBound() and UBound() functions.
I agree with everything Cody stated.
If you really wanted to you could loop through the string character by character and count the number of times you find your delimiter. In your example, it is space delimited, so you would simply count the number of spaces and add 1, but as Cody stated, those are not separate values..
Are you trying to parse text here or what? Regardless, I think what you really need to do is store your data into an array. Make your life easier, not more difficult.

How to remove these kind of symbols (junk) from string?

Imagine I have String in C#: "I Don’t see ya.."
I want to remove (replace to nothing or etc.) these "’" symbols.
How do I do this?
That 'junk' looks a lot like someone interpreted UTF-8 data as ISO 8859-1 or Windows-1252, probably repeatedly.
’ is the sequence C3 A2, E2 82 AC, E2 84 A2.
UTF-8 C3 A2 = U+00E2 = â
UTF-8 E2 82 AC = U+20AC = €
UTF-8 E2 84 A2 = U+2122 = ™
We then do it again: in Windows 1252 this sequence is E2 80 99, so the character should have been U+2019, RIGHT SINGLE QUOTATION MARK (’)
You could make multiple passes with byte arrays, Encoding.UTF8 and Encoding.GetEncoding(1252) to correctly turn the junk back into what was originally entered. You will need to check your processing to find the two places that UTF-8 data was incorrectly interpreted as Windows-1252.
"I Don’t see ya..".Replace( "’", string.Empty);
How did that junk get in there the first place? That's the real question.
By removing any non-latin character you'll be intentionally breaking some internationalization support.
Don't forget the poor guy who's name has a "â" in it.
This looks disturbingly familiar to a character encoding issue dealing with the Windows character set being stored in a database using the standard character encoding. I see someone voted Will down, but he has a point. You may be solving the immediate issue, but the combinations of characters are limitless if this is the issue.
If you really have to do this, regular expressions are probably the best solution.
I would strongly recommend that you think about why you have to do this, though - at least some of the characters your listing as undesirable are perfectly valid and useful in other languages, and just filtering them out will most likely annoy at least some of your international users. As a swede, I can't emphasize enough how much I hate systems that can't handle our å, ä and ö characters correctly.
Consider Regex.Replace(your_string, regex, "") - that's what I use.
Test each character in turn to see if it is a valid alphabetic or numeric character and if not then remove it from the string. The character test is very simple, just use...
char.IsLetterOrDigit;
Please there are various others such as...
char.IsSymbol;
char.IsControl;
Regex.Replace("The string", "[^a-zA-Z ]","");
That's how you'd do it in C#, although that regular expression ([^a-zA-Z ]) should work in most languages.
[Edited: forgot the space in the regex]
The ASCII / Integer code for these characters would be out of the normal alphabetic Ranges. Seek and replace with empty characters. String has a Replace method I believe.
Either use a blacklist of stuff you do not want, or preferably a white list (set). With a white list you iterate over the string and only copy the letters that are in your white list to the result string. You said remove, and the way you do that is having two pointers one you read from (R) and one you write to (W):
I Donââ‚
W R
if comma is in your whitelist then you would in this case read the comma and write it where à is then advance both pointers. UTF-8 is a multi-byte encoding, so you advancing the pointer may not just be adding to the address.
With C an easy to way to get a white list by using one of the predefined functions (or macros): isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit. In this case you send up with a white list function instead of a set of course.
Usually when I see data like you have I look for memory corruption, or evidence to suggest that the encoding I expect is different than the one the data was entered with.
/Allan
I had the same problem with extraneous junk thrown in by adobe in an EXIF dump. I spent an hour looking for a straight answer and trying numerous half-baked suggestions which did not work here.
This thread more than most I have read was replete with deep, probing questions like 'how did it get there?', 'what if somebody has this character in their name?', 'are you sure you want to break internationalization?'.
There were some impressive displays of erudition positing how this junk could have gotten here and explaining the evolution of the various character encoding schemes. The person wanted to know how to remove it, not how it came to be or what the standards orgs are up to, interesting as this trivia may be.
I wrote a tiny program which gave me the right answer. Instead of paraphrasing the main concept, here is the entire, self-contained, working (at least on my system) program and the output I used to nuke the junk:
#!/usr/local/bin/perl -w
# This runs in a dos window and shows the char, integer and hex values
# for the weird chars. Install the HEX values in the REGEXP below until
# the final test line looks normal.
$str = 's: “Brian'; # Nuke the 3 werid chars in front of Brian.
#str = split(//, $str);
printf("len str '$str' = %d, scalar \#str = %d\n",
length $str, scalar #str);
$ii = -1;
foreach $c (#str) {
$ii++;
printf("$ii) char '$c', ord=%03d, hex='%s'\n",
ord($c), unpack("H*", $c));
}
# Take the hex characters shown above, plug them into the below regexp
# until the junk disappears!
($s2 = $str) =~ s/[\xE2\x80\x9C]//g; # << Insert HEX values HERE
print("S2=>$s2<\n"); # Final test
Result:
M:\new\6s-2014.1031-nef.halloween>nuke_junk.pl
len str 's: GÇ£Brian' = 11, scalar #str = 11
0) char 's', ord=115, hex='73'
1) char ':', ord=058, hex='3a'
2) char ' ', ord=032, hex='20'
3) char 'G', ord=226, hex='e2'
4) char 'Ç', ord=128, hex='80'
5) char '£', ord=156, hex='9c'
6) char 'B', ord=066, hex='42'
7) char 'r', ord=114, hex='72'
8) char 'i', ord=105, hex='69'
9) char 'a', ord=097, hex='61'
10) char 'n', ord=110, hex='6e'
S2=>s: Brian<
It's NORMAL!!!
One other actionable, working suggestion I ran across:
iconv -c -t ASCII < 6s-2014.1031-238246.halloween.exf.dif > exf.ascii.dif
If String having the any Junk date , This is good to way remove those junk date
string InputString = "This is grate kingdom¢Ã‚¬â";
string replace = "’";
string OutputString= Regex.Replace(InputString, replace, "");
//OutputString having the following result
It's working good to me , thanks for looking this review.

Resources