move strip methods into cpp

This commit is contained in:
blueloveTH 2024-02-05 14:48:00 +08:00
parent f55c3d7206
commit 8f11ce0466
5 changed files with 119 additions and 72 deletions

View File

@ -65,8 +65,10 @@ struct Str{
const char* c_str() const; const char* c_str() const;
std::string_view sv() const; std::string_view sv() const;
std::string str() const; std::string str() const;
Str lstrip() const; Str strip(bool left, bool right, const Str& chars) const;
Str strip() const; Str strip(bool left=true, bool right=true) const;
Str lstrip() const { return strip(true, false); }
Str rstrip() const { return strip(false, true); }
Str lower() const; Str lower() const;
Str upper() const; Str upper() const;
Str escape(bool single_quote=true) const; Str escape(bool single_quote=true) const;

View File

@ -86,7 +86,7 @@ def sorted(iterable, key=None, reverse=False):
return a return a
##### str ##### ##### str #####
def __f(self: str, *args, **kwargs) -> str: def __format_string(self: str, *args, **kwargs) -> str:
def tokenizeString(s: str): def tokenizeString(s: str):
tokens = [] tokens = []
L, R = 0,0 L, R = 0,0
@ -195,59 +195,8 @@ def __f(self: str, *args, **kwargs) -> str:
return ''.join(final_tokens) return ''.join(final_tokens)
str.format = __f str.format = __format_string
del __format_string
def __f(self, chars=None):
chars = chars or ' \t\n\r'
i = 0
while i < len(self) and self[i] in chars:
++i
return self[i:]
str.lstrip = __f
def __f(self, chars=None):
chars = chars or ' \t\n\r'
j = len(self) - 1
while j >= 0 and self[j] in chars:
--j
return self[:j+1]
str.rstrip = __f
def __f(self, chars=None):
chars = chars or ' \t\n\r'
i = 0
while i < len(self) and self[i] in chars:
++i
j = len(self) - 1
while j >= 0 and self[j] in chars:
--j
return self[i:j+1]
str.strip = __f
def __f(self, width: int):
delta = width - len(self)
if delta <= 0:
return self
return '0' * delta + self
str.zfill = __f
def __f(self, width: int, fillchar=' '):
delta = width - len(self)
if delta <= 0:
return self
assert len(fillchar) == 1
return fillchar * delta + self
str.rjust = __f
def __f(self, width: int, fillchar=' '):
delta = width - len(self)
if delta <= 0:
return self
assert len(fillchar) == 1
return self + fillchar * delta
str.ljust = __f
del __f
def help(obj): def help(obj):

View File

@ -641,6 +641,74 @@ void init_builtins(VM* _vm) {
return VAR(self.upper()); return VAR(self.upper());
}); });
_vm->bind(_vm->_t(VM::tp_str), "strip(self, chars=None)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
if(args[1] == vm->None){
return VAR(self.strip());
}else{
const Str& chars = CAST(Str&, args[1]);
return VAR(self.strip(true, true, chars));
}
});
_vm->bind(_vm->_t(VM::tp_str), "lstrip(self, chars=None)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
if(args[1] == vm->None){
return VAR(self.lstrip());
}else{
const Str& chars = CAST(Str&, args[1]);
return VAR(self.strip(true, false, chars));
}
});
_vm->bind(_vm->_t(VM::tp_str), "rstrip(self, chars=None)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
if(args[1] == vm->None){
return VAR(self.rstrip());
}else{
const Str& chars = CAST(Str&, args[1]);
return VAR(self.strip(false, true, chars));
}
});
// zfill
_vm->bind(_vm->_t(VM::tp_str), "zfill(self, width)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
int width = CAST(int, args[1]);
int delta = width - self.u8_length();
if(delta <= 0) return args[0];
SStream ss;
for(int i=0; i<delta; i++) ss << '0';
ss << self;
return VAR(ss.str());
});
// ljust
_vm->bind(_vm->_t(VM::tp_str), "ljust(self, width, fillchar=' ')", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
int width = CAST(int, args[1]);
int delta = width - self.u8_length();
if(delta <= 0) return args[0];
const Str& fillchar = CAST(Str&, args[2]);
SStream ss;
ss << self;
for(int i=0; i<delta; i++) ss << fillchar;
return VAR(ss.str());
});
// rjust
_vm->bind(_vm->_t(VM::tp_str), "rjust(self, width, fillchar=' ')", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
int width = CAST(int, args[1]);
int delta = width - self.u8_length();
if(delta <= 0) return args[0];
const Str& fillchar = CAST(Str&, args[2]);
SStream ss;
for(int i=0; i<delta; i++) ss << fillchar;
ss << self;
return VAR(ss.str());
});
// tp_list / tp_tuple // tp_list / tp_tuple
_vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) { _vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
List& self = _CAST(List&, args[0]); List& self = _CAST(List&, args[0]);

View File

@ -194,24 +194,32 @@ int utf8len(unsigned char c, bool suppress){
return std::string(data, size); return std::string(data, size);
} }
Str Str::lstrip() const { Str Str::strip(bool left, bool right, const Str& chars) const {
std::string copy(data, size); int L = 0;
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) { int R = u8_length();
// std::isspace(c) does not working on windows (Debug) if(left){
return c != ' ' && c != '\t' && c != '\r' && c != '\n'; while(L < R && chars.index(u8_getitem(L)) != -1) L++;
})); }
return Str(copy); if(right){
while(L < R && chars.index(u8_getitem(R-1)) != -1) R--;
}
return u8_slice(L, R, 1);
} }
Str Str::strip() const { Str Str::strip(bool left, bool right) const {
std::string copy(data, size); if(is_ascii){
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) { int L = 0;
return c != ' ' && c != '\t' && c != '\r' && c != '\n'; int R = size;
})); if(left){
copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](char c) { while(L < R && (data[L] == ' ' || data[L] == '\t' || data[L] == '\n' || data[L] == '\r')) L++;
return c != ' ' && c != '\t' && c != '\r' && c != '\n'; }
}).base(), copy.end()); if(right){
return Str(copy); while(L < R && (data[R-1] == ' ' || data[R-1] == '\t' || data[R-1] == '\n' || data[R-1] == '\r')) R--;
}
return substr(L, R - L);
}else{
return strip(left, right, " \t\n\r");
}
} }
Str Str::lower() const{ Str Str::lower() const{

View File

@ -69,6 +69,26 @@ assert s.strip( '12' ) == "3abcrunoob3"
assert t.strip( '*' ) == "this is **string** example....wow!!!" assert t.strip( '*' ) == "this is **string** example....wow!!!"
assert s.strip( '12' ) == "3abcrunoob3" assert s.strip( '12' ) == "3abcrunoob3"
assert '测试123'.strip('测试') == '123'
assert '测试123测试'.strip('测试') == '123'
assert '123测试'.strip('2') == '123测试'
assert '测试123'.strip('') == '试123'
assert '测试123'.strip('') == '测试123'
assert '测试123测试'.lstrip('测试') == '123测试'
assert '测试123测试'.rstrip('测试') == '测试123'
assert 'abc'.lstrip('a') == 'bc'
assert 'abc'.lstrip('b') == 'abc'
assert 'abc'.lstrip('c') == 'abc'
assert 'abc'.rstrip('a') == 'abc'
assert 'abc'.rstrip('b') == 'abc'
assert 'abc'.rstrip('c') == 'ab'
assert 'abc'.lstrip('abc') == ''
assert 'abc'.rstrip('abc') == ''
assert 'abc'.strip('abc') == ''
s = ' asd\n asd \n' s = ' asd\n asd \n'
assert s.strip() == 'asd\n asd' assert s.strip() == 'asd\n asd'