I have a string which is looking like this for example Lübeck Nürnberg Österreich with "Umlaute".
Now I want to split it and add the new "words" on the string like this Lübeck Nürnberg Österreich Luebeck Nuernberg Oesterreich.
So ä should be ae, ö should be oe and ü should be ue.
But I have no clue how to achieve this, thank you!
DATA: lt_split TYPE TABLE OF char40.
SPLIT string AT space INTO TABLE lt_split.
You can use REPLACE to replace a string with another string inside a string:
REPLACE ALL OCCURENCES OF: 'ä'
IN string
WITH 'ae',
'ü'
IN string
WITH 'ue'.
There is another variation of this statement, it can be used with an internal table:
REPLACE 'ä'
IN TABLE lt_split
WITH 'ae'.
https://help.sap.com/doc/abapdocu_751_index_htm/7.51/de-DE/abapreplace_in_pattern.htm
Please note, the new string will be longer (if at least one replacement happened), this can be a problem, if the string was character type with fixed length and the new string would be longer, than allowed.
You can use the function module SCP_REPLACE_STRANGE_CHARS, but you have less control than replace on what is changed.
Example:
DATA name TYPE string.
name = 'Lübeck Österreich Haßberge Eichstätt'.
CALL FUNCTION 'SCP_REPLACE_STRANGE_CHARS'
EXPORTING
intext = name
IMPORTING
outtext = name
EXCEPTIONS
invalid_codepage = 1
codepage_mismatch = 2
internal_error = 3
cannot_convert = 4
fields_not_type_c = 5
OTHERS = 6.
ASSERT name = 'Luebeck Oesterreich Hassberge Eichstaett'.
Be careful, the function module affects lots of characters with accent and lots of special characters, for instance, depending on the values of parameters, we may have these replacements:
á ==> AE
ā ==> A (Acircumflex)
Ă ==> Ae (Adieresis)
£ ==> L (sterling)
ß ==> ss (eszett)
¼ ==> 1/4
You may use the program RSCP0007 to test the function module.
Is there a built in way, or reasonably standard package that allows you to convert a standard UUID into a short string that would enable shorter URL's?
I.e. taking advantage of using a larger range of characters such as [A-Za-z0-9] to output a shorter string.
I know we can use base64 to encode the bytes, as follows, but I'm after something that creates a string that looks like a "word", i.e. no + and /:
id = base64.StdEncoding.EncodeToString(myUuid.Bytes())
A universally unique identifier (UUID) is a 128-bit value, which is 16 bytes. For human-readable display, many systems use a canonical format using hexadecimal text with inserted hyphen characters, for example:
123e4567-e89b-12d3-a456-426655440000
This has length 16*2 + 4 = 36. You may choose to omit the hypens which gives you:
fmt.Printf("%x\n", uuid)
fmt.Println(hex.EncodeToString(uuid))
// Output: 32 chars
123e4567e89b12d3a456426655440000
123e4567e89b12d3a456426655440000
You may choose to use base32 encoding (which encodes 5 bits with 1 symbol in contrast to hex encoding which encodes 4 bits with 1 symbol):
fmt.Println(base32.StdEncoding.EncodeToString(uuid))
// Output: 26 chars
CI7EKZ7ITMJNHJCWIJTFKRAAAA======
Trim the trailing = signs when transmitting, so this will always be 26 chars. Note that you have to append "======" prior to decode the string using base32.StdEncoding.DecodeString().
If this is still too long for you, you may use base64 encoding (which encodes 6 bits with 1 symbol):
fmt.Println(base64.RawURLEncoding.EncodeToString(uuid))
// Output: 22 chars
Ej5FZ-ibEtOkVkJmVUQAAA
Note that base64.RawURLEncoding produces a base64 string (without padding) which is safe for URL inclusion, because the 2 extra chars in the symbol table (beyond [0-9a-zA-Z]) are - and _, both which are safe to be included in URLs.
Unfortunately for you, the base64 string may contain 2 extra chars beyond [0-9a-zA-Z]. So read on.
Interpreted, escaped string
If you are alien to these 2 extra characters, you may choose to turn your base64 string into an interpreted, escaped string similar to the interpreted string literals in Go. For example if you want to insert a backslash in an interpreted string literal, you have to double it because backslash is a special character indicating a sequence, e.g.:
fmt.Println("One backspace: \\") // Output: "One backspace: \"
We may choose to do something similar to this. We have to designate a special character: be it 9.
Reasoning: base64.RawURLEncoding uses the charset: A..Za..z0..9-_, so 9 represents the highest code with alphanumeric character (61 decimal = 111101b). See advantage below.
So whenever the base64 string contains a 9, replace it with 99. And whenever the base64 string contains the extra characters, use a sequence instead of them:
9 => 99
- => 90
_ => 91
This is a simple replacement table which can be captured by a value of strings.Replacer:
var escaper = strings.NewReplacer("9", "99", "-", "90", "_", "91")
And using it:
fmt.Println(escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid)))
// Output:
Ej5FZ90ibEtOkVkJmVUQAAA
This will slightly increase the length as sometimes a sequence of 2 chars will be used instead of 1 char, but the gain will be that only [0-9a-zA-Z] chars will be used, as you wanted. The average length will be less than 1 additional character: 23 chars. Fair trade.
Logic: For simplicity let's assume all possible uuids have equal probability (uuid is not completely random, so this is not the case, but let's set this aside as this is just an estimation). Last base64 symbol will never be a replaceable char (that's why we chose the special char to be 9 instead of like A), 21 chars may turn into a replaceable sequence. The chance for one being replaceable: 3 / 64 = 0.047, so on average this means 21*3/64 = 0.98 sequences which turn 1 char into a 2-char sequence, so this is equal to the number of extra characters.
To decode, use an inverse decoding table captured by the following strings.Replacer:
var unescaper = strings.NewReplacer("99", "9", "90", "-", "91", "_")
Example code to decode an escaped base64 string:
fmt.Println("Verify decoding:")
s := escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid))
dec, err := base64.RawURLEncoding.DecodeString(unescaper.Replace(s))
fmt.Printf("%x, %v\n", dec, err)
Output:
123e4567e89b12d3a456426655440000, <nil>
Try all the examples on the Go Playground.
As suggested here, If you want just a fairly random string to use as slug, better to not bother with UUID at all.
You can simply use go's native math/rand library to make random strings of desired length:
import (
"math/rand"
"encoding/hex"
)
b := make([]byte, 4) //equals 8 characters
rand.Read(b)
s := hex.EncodeToString(b)
Another option is math/big. While base64 has a constant output of 22
characters, math/big can get down to 2 characters, depending on the input:
package main
import (
"encoding/base64"
"fmt"
"math/big"
)
type uuid [16]byte
func (id uuid) encode() string {
return new(big.Int).SetBytes(id[:]).Text(62)
}
func main() {
var id uuid
for n := len(id); n > 0; n-- {
id[n - 1] = 0xFF
s := base64.RawURLEncoding.EncodeToString(id[:])
t := id.encode()
fmt.Printf("%v %v\n", s, t)
}
}
Result:
AAAAAAAAAAAAAAAAAAAA_w 47
AAAAAAAAAAAAAAAAAAD__w h31
AAAAAAAAAAAAAAAAAP___w 18owf
AAAAAAAAAAAAAAAA_____w 4GFfc3
AAAAAAAAAAAAAAD______w jmaiJOv
AAAAAAAAAAAAAP_______w 1hVwxnaA7
AAAAAAAAAAAA_________w 5k1wlNFHb1
AAAAAAAAAAD__________w lYGhA16ahyf
AAAAAAAAAP___________w 1sKyAAIxssts3
AAAAAAAA_____________w 62IeP5BU9vzBSv
AAAAAAD______________w oXcFcXavRgn2p67
AAAAAP_______________w 1F2si9ujpxVB7VDj1
AAAA_________________w 6Rs8OXba9u5PiJYiAf
AAD__________________w skIcqom5Vag3PnOYJI3
AP___________________w 1SZwviYzes2mjOamuMJWv
_____________________w 7N42dgm5tFLK9N8MT7fHC7
https://golang.org/pkg/math/big
How can I convert a character code to a string character in Lua?
E.g.
d = 48
-- this is what I want
str_d = "0"
You are looking for string.char:
string.char (···)
Receives zero or more integers. Returns a string with length equal to the number of arguments, in which each character has the internal numerical code equal to its corresponding argument.
Note that numerical codes are not necessarily portable across platforms.
For your example:
local d = 48
local str_d = string.char(d) -- str_d == "0"
For ASCII characters, you can use string.char.
For UTF-8 strings, you can use utf8.char(introduced in Lua 5.3) to get a character from its code point.
print(utf8.char(48)) -- 0
print(utf8.char(29790)) -- 瑞
Let's say I want to "underline" a string with dots with Python3 :
Everything's fine with ASCII characters : I get the length with len(mystring) and I write as much dots as needed. Here is an example with a string whose length is 8 :
mystring
........
But with non-ASCII characters len(mystring) doesn't return the result I need; e.g. len("列島") is 2, but I need 4 dots to underline the string :
列島
....
How can I get the correct result ? Any help would be appreciated !
... unicodedata.east_asian_width() does the trick.
See by example this implementation.
I started coding with groovy today and I notices that if I take the following code:
int aaa = "6"
log.info(aaa)
The output I get is:
54 <-- (ASCII Code for '6')
If I assign aaa with any number which is beyond the range of 0..9 I get a class cast exception.
Looks like if the string is actually a single character - groovy converts its ASCII code/hashCode.
I tried this code:
int aaa = "A"
log.info(aaa)
And the output I got was:
65 <-- (ASCII code for 'A')
What is the official reason for this?
Is it because groovy automatically changes "A" into 'A'?
As Jochen says here in the JIRA; Strings of length 1 are converted to chars if needed (and by putting it into an int variable, it is assuming that that is what you want to do)
If you want to accept bigger numbers, you can do:
int a = '12345' as int
And that will convert the whole number to an int.