Crystal: how to copy String::Builder s to each other - crystal-lang

I want to write contents on one String::Builder to another, like:
str1 = String::Builder.new
str2 = String::Builder.new
str1 << "foo"
str2 << "bar"
str1.copy_somehow_another_builder(str2) #=> "foobar"
currently I just str1 << str2.to_s.
How to do it?
And is to_s'ing and pushing is same as what I want from performance point of view?

If any one meets with the problem, you can use IO::Memory for the same purpose like:
io = IO::Memory.new 128
io2 = IO::Memory.new 128
io << "foo"
io2 << "bar"
buffer = uninitialized UInt8[128]
io2.rewind
if (read_bytes_length = io2.read(buffer.to_slice)) > 0
io.write( buffer.to_slice[0, read_bytes_length] )
end
p io.to_s #=> "foobar"

Related

scala - how to substitute env value for another variable using regex

I have a variable aa which is having reference to an environment variable.
And I need to substitute the value using regex
Name = TEMP
Value = C:\Users\asus101\AppData\Local\Temp
aa: String = "${TEMP}_Report"
Expected output:
p2: C:\Users\asus101\AppData\Local\Temp_Report
The code that I tried
import scala.collection.JavaConversions._
val aa = "${TEMP}\\Report"
for ((name,value) <- System.getenv() ) {
val p1 = """\${XX}""".replace("XX",name).r
val p2 = p1.replaceAllIn(aa,value)
if(name=="TEMP") {
println("Name = " + name)
println("Value = " + value)
println("p2 = " + p2 )
}
I'm getting the error as
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 1
\${USERDOMAIN_ROAMINGPROFILE}
^
what is wrong with the regex
It's a little hard to tell, but I think this gets at what you're after.
import scala.util.Properties._
val pttrn = raw".*(\$$\{\s*(\w+)\s*\})".r
val strA = "${ME}:my ${HOME} is Gnome and my ${BROWSER} is fine."
val strB =
strA.split("(?<=})").map {
case s # pttrn(a,b) => envOrNone(b).fold(s)(s.replace(a,_))
case s => s
}.mkString
//strB: String = ${ME}:my /home/jwvh is Gnome and my firefox is fine.
There is no $ME in my environment, so no substitution there, but the $HOME and $BROWSER values are pulled out and substituted.

C++ regex replace with a callback function

I have a map that stores id to value mapping, an input string can contain a bunch of ids. I need to replace those ids with their corresponding values. For example:
string = "I am in #1 city, it is now #2 time" // (#1 and #2 are ids here)
id_to_val_map = {1 => "New York", 2 => "summer"}
Desired output:
"I am in New York city, it is now summer time"
Is there a way I can have a callback function (that takes in the matched string and returns the string to be used as replacement) ? std::regex_replace doesn't seem to support that.
The alternative is to find all the matches, then compute their replacement values, and then perform the actual replacement. Which won't be that efficient.
You might do:
const std::map<int, std::string> m = {{1, "New York"}, {2, "summer"}};
std::string s = "I am in #1 city, it is now #2 time";
for (const auto& [id, value] : m) {
s = std::regex_replace(s, std::regex("#" + std::to_string(id)), value);
}
std::cout << s << std::endl;
Demo
A homegrown way is to use a while loop with regex_search() then
build the output string as you go.
This is essentially what regex_replace() does in a single pass.
No need to do a separate regex for each map item which has overhead of
reassignment on every item ( s=regex_replace() ) as well as covering the same
real estate with every pass.
Something like this regex
(?s)
( .*? ) # (1)
(?:
\#
( \d+ ) # (2)
| $
)
with this code
typedef std::string::const_iterator SITR;
typedef std::smatch X_smatch;
#define REGEX_SEARCH std::regex_search
std::regex _Rx = std::regex( "(?s)(.*?)(?:\\#(\\d+)|$)" );
SITR start = oldstr.begin();
SITR end = oldstr.end();
X_smatch m;
std::string newstr = "";
while ( REGEX_SEARCH( start, end, m, _Rx ) )
{
newstr.append( m[1].str() );
if ( m[2].matched ) {
{
// append the map keys value here, do error checking etc..
// std::string key = m[2].str();
int ndx = std::atoi( m[2].str() );
newstr.append( mymap[ ndx ] );
}
start = m[0].second;
}
// assign the old string with new string if need be
oldstr = newstr;

Find regex matches & remove outer part of the match

I have a string
content = "std::cout << func(some_val) << std::endl; auto i = func(some_other_val);"
and I find to find all instances with func(...), and remove the function call. So that I would get
content = "std::cout << some_val << std::endl; auto i = some_other_val;"
So I've tried this:
import re
content = "std::cout << func(some_val) << std::endl; auto i = func(some_other_val);"
c = re.compile('func\([a-zA-Z0-9_]+\)')
print(c.sub('', content)) # gives "std::cout << << std::endl; auto i = ;"
but this removes the entire match, not just the func( and ).
Basically, how do I keep whatever matched with [a-zA-Z0-9_]+?
You can use re.sub to replace all the outer func(...) with only the value like below, See regex here , Here I've used [w]+, you can do changes if you use
import re
regex = r"func\(([\w]+)\)"
test_str = "std::cout << func(some_val) << std::endl; auto i = func(some_other_val);"
subst = "\\1"
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)
if result:
print (result)
Demo: https://rextester.com/QZJLF65281
Output:
std::cout << some_val << std::endl; auto i = some_other_val;
You should capture the part of the match that you want to keep into a group:
re.compile(r'func\(([a-zA-Z0-9_]+)\)')
Here I captured it into group 1.
And then you can refer to group 1 with \1:
print(c.sub(r'\1', content))
Note that in general, you should not use regex to parse source code of a non-regular language (such as C in this case) with regex. It might work in a few very specific cases, where the input is very limited, but you should still use a C parser to parse C code. I have found libraries such as this and this.

Trying to split a long String into List ( which each var in the list represent a word) using Python

Given (for example):
text = "Hello world Hello Stack"
I need to make a list which contains each word (only) in text.
The list should look like:
the_list = ["Hello","world","Hello","Stack"]
I tried to do that by
the_list = text.split(' ')
Of course, it doesn't work.
Can someone explain me what should I write in order to get the ideal list?
You're very close. You can just call text.split without any arguments and it should work.
text = "Hello world Hello Stack"
the_list = text.split()
using regex library we can achieve you want to get
import re
text = "Hello world Hello Stack"
answer = re.sub("[^\w]", " ", text).split()
Regular expressions would work in this case
text = "Hello world Hello Stack"
import re
my_list = re.sub(r'\s+', ' ', text).split(' ') #replacing one or more whitespaces with a single whitespace
print my_list #prints ['Hello', 'world', 'Hello', 'Stack']
Works fine on Python 3
text = "Hello world Hello Stack"
the_list = []
t = ''
count = 0
for char in text:
count += 1
if len(the_list) > 0 and the_list[len(the_list) - 1] == ' ':
del the_list[len(the_list) - 1]
t += char
if char == ' ' or count == len(text):
the_list.append(t)
t = ''
print(the_list)

c# Regex- Remove string which developed only combination of special charter

I am looking for regular expression by which I can ignore strings which is only combination of All special charters.
Example
List<string> liststr = new List<string>() { "a b", "c%d", " ", "% % % %" ,"''","&","''","'"}; etc...
I need result of this one
{ "a b", "c%d"}
You can use this, too, to match string without any Unicode letter:
var liststr = new List<string>() { "a b", "c%d", " ", "% % % %", "''", "&", "''", "'" };
var rx2 = #"^\P{L}+$";
var res2 = liststr.Where(p => !Regex.IsMatch(p, rx2)).ToList();
Output:
I also suggest creating the regex object as a private static readonly field, with Compiled option, so that performance is not impacted.
private static readonly Regex rx2 = new Regex(#"^\P{L}+", RegexOptions.Compiled);
... (and inside the caller)
var res2 = liststr.Where(p => !rx2.IsMatch(p)).ToList();
Use this one :
.*[A-Za-z0-9].*
It matches at least one alphanumeric character. Doing this, it will take any string that is not only symbols/special chars. It does the output you want, see here : demo
You can use a very simple regex like
Regex regex = new Regex(#"^[% &']+$");
Where
[% &'] Is the list of special characters that you wish to include
Example
List<string> liststr = new List<string>() { "a b", "c%d", " ", "% % % %" ,"''","&","''","'"};
List<string> final = new List<string>();
Regex regex = new Regex(#"^[% &']+$");
foreach ( string str in liststr)
{
if (! regex.IsMatch(str))
final.Add(str);
}
Will give an output as
final = {"a b", "c%d"}