Concatenate strings in ocaml with newline between them - ocaml

I'd like to do something like this
String.concat '\n' [str1; str2 ... strn]
so I can print in a file. But ocaml doesn't allow me to do that. What can I do?

String.concat "\n" [str1; str2 ... strn]
works fine. The problem is that you used '\n', which is a character literal, not a string. Example:
# String.concat '\n' ["abc"; "123"];;
Error: This expression has type char but an expression was expected of type
string
# String.concat "\n" ["abc"; "123"];;
- : string = "abc\n123"

If you're using Jane Street's base module for your standard library you'll have to do it like so:
# #require "base";;
# open! Base;;
# String.concat ~sep:"\n" ["abc"; "123"];;
- : string = "abc\n123"
Jane Street really likes to take advantage of named arguments.

Related

Str.global_replace in OCaml putting carats where they shouldn't be

I am working to convert multiline strings into a list of tokens that might be easier for me to work with.
In accordance with the specific needs of my project, I'm padding any carat symbol that appears in my input with spaces, so that "^" gets turned into " ^ ". I'm using something like the following function to do so:
let bad_function string = Str.global_replace (Str.regexp "^") " ^ " (string)
I then use something like the below function to then turn this multiline string into a list of tokens (ignoring whitespace).
let string_to_tokens string = (Str.split (Str.regexp "[ \n\r\x0c\t]+") (string));;
For some reason, bad_function adds carats to places where they shouldn't be. Take the following line of code:
(bad_function " This is some
multiline input
with newline characters
and tabs. When I convert this string
into a list of tokens I get ^s showing up where
they shouldn't. ")
The first line of the string turns into:
^ This is some \n ^
When I feed the output from bad_function into string_to_tokens I get the following list:
string_to_tokens (bad_function " This is some
multiline input
with newline characters
and tabs. When I convert this string
into a list of tokens I get ^s showing up where
they shouldn't. ")
["^"; "This"; "is"; "some"; "^"; "multiline"; "input"; "^"; "with";
"newline"; "characters"; "^"; "and"; "tabs."; "When"; "I"; "convert";
"this"; "string"; "^"; "into"; "a"; "list"; "of"; "tokens"; "I"; "get";
"^s"; "showing"; "up"; "where"; "^"; "they"; "shouldn't."]
Why is this happening, and how can I fix so these functions behave like I want them to?
As explained in the Str module.
^ Matches at beginning of line: either at the beginning of the
matched string, or just after a '\n' character.
So you have to quote the '^' character using the escape character "\".
However, note that (also from the doc)
any backslash character in the regular expression must be doubled to
make it past the OCaml string parser.
This means you have to put a double '\' to do what you want without getting a warning.
This should do the job:
let bad_function string = Str.global_replace (Str.regexp "\\^") " ^ " (string);;

Formatting numbers with thousand separators

Is there anything in the standard library or in Core that I can use to format integers with thousand separators?
Unfortunately, nothing, expect that you can use the %a format specifier and provide your own pretty-printer.
You could use a %#d format to print an integer using underscores as separators (following OCaml lexical conventions):
# Printf.sprintf "=> %#d" 1000000;;
- : string = "=> 1_000_000"
And then replace underscores with commas:
# Printf.sprintf "=> %#d" 1000000 |> String.map (function '_' -> ',' | char -> char);;
- : string = "=> 1,000,000"

String sanitization to escape special characters

Hi I would like to build a function which will replace all the special character ie: * & ! # # $ % with "//(with whatever the match will be)
so I string like "1*234#" will become 1//*/234//#"
is there a replace function in swift to do that?
String.replacingOccurrences which can be used like so:
let replacements = ["!" : "-exclamation-", "." : "-period-"]
var stringToModify = "hello! This is a string."
replacements.keys.forEach { stringToModify = stringToModify.replacingOccurrences(of: $0, with: replacements[$0]!)}
print(stringToModify)
output: hello -exclamation- This is a string -period-
There is also an overload with more options, incase you want to do stuff like case insensitive compare. https://developer.apple.com/reference/foundation/nsstring/1416484-replacingoccurrences

Scala: How to replace all consecutive underscore with a single space?

I want to replace all the consecutive underscores with a single space. This is the code that I have written. But it is not replacing anything. Below is the code that I have written. What am I doing wrong?
import scala.util.matching.Regex
val regex: Regex = new Regex("/[\\W_]+/g")
val name: String = "cust_id"
val newName: String = regex.replaceAllIn(name, " ")
println(newName)
Answer: "cust_id"
You could use replaceAll to do the job without regex :
val name: String = "cust_id"
val newName: String = name.replaceAll("_"," ")
println(newName)
The slashes in your regular expression don't belong there.
new Regex("[\\W_]+", "g").replaceAllIn("cust_id", " ")
// "cust id"
A string in Scala may be treated as a collection, hence we can map over it and in this case apply pattern matching to substitute characters, like this
"cust_id".map {
case '_' => " "
case c => c
}.mkString
Method mkString glues up the vector of characters back onto a string.

How do I insert format str and don't remove the matched regular expression in input string in boost::regex_replace() in C++?

I want to put space between punctuations and other words in a sentence. But boost::regex_replace() replaces the punctuation with space, and I want to keep a punctuation in the sentence!
for example in this code the output should be "Hello . hi , "
regex e1("[.,]");
std::basic_string<char> str = "Hello.hi,";
std::basic_string<char> fmt = " ";
cout<<regex_replace(str, e1, fmt)<<endl;
Can you help me?
You need to use a replacement variable in your fmt string. If I understand the documentation correctly, then in the absence of a flags field, you'll want to use a Boost-Extended format string.
In that sub-language, you use $& to mean whatever was matched, so you should try defining fmt as:
std::basic_string<char> fmt = " $& ";
That should change each punctuation into that same character, surrounded by spaces.