In sapscript, how do I trim/offset from the right of a string? - sapscript

I have a need in SAPScript to trim a string from the right. There doesn't appear to be a function to accomplish this. &myfield+3& only trims from the left.
Is there a way to trim from the right? Can offset accept a negative value?

My ultimate goal was to take a number such as a quantity; 12.43 and convert that to: 001243.
6 characters long
padded left with zeroes
no special characters (decimals or thousands separators)
Ultimately I had to first define a field and do the intial number formatting:
/:DEFINE &myfield& = &qtyfield(.2CT)&
The above
sets the number to 2 decimal points (.2)
space compreession (C)
removes the thousands separator (T)
Then I call a function within our print routine to do the special character stripping as such:
/:PERFORM get_unformatted_value IN PROGRAM zbc_rle_ean128_label
/:USING &myfield&
/:CHANGING &myfield&
/:ENDPERFORM
Then I can do the final output as such:
/ &myfield(K6RF0)&
which:
Ignores any conversions (K)
Sets output length to 6 and right aligns it (6R)
and left pad with zeros (F0)
That seems to work for me. Hopefully this helps someone!

Related

Extract multiple substrings of numbers of a specific length from string in Google Sheets

I'd need to split or extract only numbers made of 8 digits from a string in Google Sheets.
I've tried with SPLIT or REGEXREPLACE but I can't find a way to get only the numbers of that length, I only get all the numbers in the string!
For example I'm using
=SPLIT(lower(N2),"qwertyuiopasdfghjklzxcvbnm`-=[]\;' ,./!:##$%^&*()")
but I get all the numbers while I only need 8 digits numbers.
This may be a test value:
00150412632BBHBBLD 12458 32354 1312548896 ACT inv 62345471
I only need to extract "62345471" and nothing else!
Could you please help me out?
Many thanks!
Please use the following formula for a single cell.
Drag it down for more cells.
=INDEX(TRANSPOSE(QUERY(TRANSPOSE(IF(LEN(SPLIT(REGEXREPLACE(A2&" ","\D+"," ")," "))=8,
SPLIT(REGEXREPLACE(A2&" ","\D+"," ")," "),"")),"where Col1 is not null ",0)))
Functions used:
QUERY
INDEX
TRANSPOSE
IF
LEN
SPLIT
REGEXREPLACE
If you only need to do this for one cell (or you have your heart set on dragging the formula down into individual cells), use the following formula:
=REGEXEXTRACT(" "&N2&" ","\s(\d{8})\s")
However, I suspect you want to process the eight-digit number out of all cells running N2:N. If that is the case, clear whatever will be your results column (including any headers) and place the following in the top cell of that otherwise cleared results column:
=ArrayFormula({"Your Header"; IF(N2:N="",,IFERROR(REGEXEXTRACT(" "&N2:N&" ","\s(\d{8})\s")))})
Replace the header text Your Header with whatever you want your actual header text to be. The formula will show that header text and will return all results for all rows where N2:N is not null. Where no eight-digit number is found, null will be returned.
By prepending and appending a space to the N2:N raw strings before processing, spaces before and after string components can be used to determine where only eight digits exist together (as opposed to eight digits within a longer string of digits).
The only assumption here is that there are, in fact, spaces between string components. I did not assume that the eight-digit number will always be in a certain position (e.g., first, last) within the string.
Try this, take a look at Example sheet
=FILTER(TRANSPOSE(SPLIT(B2," ")),LEN(TRANSPOSE(SPLIT(B2," ")))=8)
Or this to get them all.
=JOIN(" ,",FILTER(TRANSPOSE(SPLIT(B2," ")),LEN(TRANSPOSE(SPLIT(B2," ")))=8))
Explanation
SPLIT with the dilimiter set to " " space TRANSPOSE and FILTER TRANSPOSE(SPLIT(B2," ") with the condition1 set to LEN(TRANSPOSE(SPLIT(B2," "))) is = 8
JOIN the outputed column whith " ," to gat all occurrences of number with a length of 8
Note: to get the numbers with the length of N just replace 8 in the FILTER function with a cell refrence.
Using this on a cell worked just fine for me:
(cell_with_data)=REGEXEXTRACT(A1,"[0-9]{8}$")

matlab: truncate large text and append '...'

I have a large array of text (text, stored as cell-array), that I want to truncate in matlab, say for 5 characters. Truncating with regexprep is quite efficient, but now, I would love to append a '...' at the end of every truncated match (and only there).
(How) can this be achieved within MATLAB's regexprep?
>> text = {'123456780','1','12'}; %<- small representative sample
>> regexprep(text,'(^.{0,5})(.*)','$1') %capture first 5 characters or less in first group (and replace the text with first group captures)
ans =
1×3 cell array
{'12345'} {'1'} {'12'}
it should read:
ans =
1×3 cell array
{'12345...'} {'1'} {'12'}
You need to use
regexprep(text,'^(.{5}).+','$1...')
See the regex demo.
The main point is that you need to only trigger the replacement if a string is linger than five chars (else, you do not even need to truncate the string).
Note that regexprep returns the input string as is if there was no regex match found, thus you do not need to worry about strings that are zero to five chars long.
Details:
^ - start of string
(.{5}) - Capturing group 1 ($1): any five chars
.+ - any one or more chars, as many as possible.
Note that the string 12345... is in fact 8 characters long. You don't want to make the mistake of truncating 1234567 to 12345..., as the truncated version is longer and therefore shouldn't be truncated in the first place.
A solution that takes this into account is:
regexprep(text,'^(.{5}).{3}.+','$1...')
which will only truncate if there are more than 8 characters and, if so, will display the first 5 with the trailing ellipsis.

Joining two data sets on a variable with different character length

I'm trying to join two data sets on a variable with different character lengths with the following code, but neither works and I'm not sure why.
FROM A AS ROLLACT
LEFT JOIN MALT.CUST AS ACCOUNT
/* ON (ROLLACT.ACCTNO, BEST.) = INPUT( ACCOUNT.ACCT_NO,BEST.) */
ON INPUT (ROLLACT.ACCTNO, 30.) = INPUT( ACCOUNT.ACCT_NO,30.)
In this case ROLLACT.ACCTNO is a character variable with length 30 and ACCT_NO is a character variable with length 19.
So I'm confused why I can't convert both to a specific length (using Input(30.)) with:
ON INPUT (ROLLACT.ACCTNO, 30.) = INPUT( ACCOUNT.ACCT_NO,30.)
I'm also trying to convert both into numeric with:
ON (ROLLACT.ACCTNO, BEST.) = INPUT( ACCOUNT.ACCT_NO,BEST.)
Does anyone have suggestions about how to do this within the Proc Sql step?
You do not need to do anything special to compare character strings of different lengths. SAS will ignore the trailing spaces. Obviously if the actual value of the longer variable has more than 19 characters it will never match the value that is limited to 19 characters.
The INPUT() function does not change the length. If is used to convert strings into values. If you use a numeric informat, as in your examples, then the result is a number. But you cannot convert a 30 digit string exactly into a number. SAS stores numbers as 8 byte floating point values so the maximum number of decimal digits of precision is 15.
a simple substr does the trick : ON (SUBSTR(ROLLACT.ACCTNO, 1,19)) = ACCOUNT.ACCT_NO

Regex Verification of String in Correct Order with Delimiters in PHP

I'm trying to make a expression to verify that the string supplied is a valid format, but it seems that if I don't use regex in a few months, I forget everything I learned and have to relearn it.
My expression is supposed to match a format like this: 010L0404FFCCAANFFCC00M000000XXXXXX
The four delimiters are (L, N, K, M) which arent in the 0-9A-F hexidecimal range to indicate uniqueness must be in that order or not in the list. Each delimiter can only exist once!
It breaks down to this:
Starts off with a 3 digit numbers, which is simply ^([0-9]{3}) and is always required
Second set begins with L, and must be 2 digits + 2 digits + 6 hexdecimal and is optional
Third set begins with N and must be a 6 digit hexdecimal and is optional
The fourth set K is simply any amount of numbers and is optional
The fifth set is M and can be any 6 hexdecimals or XXXXXX to indicate nothing, it must be in multiples of 6 excluding 0, like 336699 (6) or 336699XXXXXXFFCC00 (18) and is optional
The hardest part I cant figure out making it require it in that order, and in multiples, like the L delimiter must come before and K always if it's there (the reason so I don't get variations of the same string which means the same thing with delimiters swapped). I can already parse it, I just want to verify the string is the correct format.
Any help would be appreciated, thanks.
Requiring the order isn't too bad. Just make each set optional. The regex will still match in order, so if the L section, for example, isn't there and the next character is N, it won't let L occur later since it won't match any of the rest of the regex.
I believe a direct translation of your requirements would be:
^([0-9]{3})(L[0-9]{4}[0-9A-F]{6})?(N[0-9A-F]{6})?(K[0-9]+)?(M([0-9A-F]{6}|X{6})+)?$
No real tricks, just making each group optional except for the first three digits, and adding an internal alternative for the two patterns of six digits in the M block.
^([0-9]{3})(L[0-9]{4}[0-9A-F]{6})?(N[0-9A-F]{6})?(K[0-9]+)?(M([0-9A-F]{6})+|MX{6})$

How to keep leading zero and add comma in openoffice calc formula?

I have 6 fields in a row in open office, the 1st is a word, the 2nd, 3rd, and 4th are a number with a leading zero, the 5th and 6th are regular numbers. How do I join them all together with a comma between them so that the leading zero stays?
Based on your comment about your numbers having a leading 0 in virtue of a custom number format, you need to incorporate TEXT() functions into your formula to retain (i.e., add) your leading 0s.
=CONCATENATE(A1,",",TEXT(B1,"0#####"),",",TEXT(C1,"0#####"),",",TEXT(D1,"0#####"),",",E1,",",F1)
Just be sure to include as many #'s as the max length of a number in that field.
Please try:
=A1&",0"&B1&",0"&C1&",0"&D1&","&E1&","&F1