1032 lines
28 KiB
Python
1032 lines
28 KiB
Python
# Copyright (c) 2015 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
"""
|
|
The module describes which operations can be done with strings in YAQL.
|
|
"""
|
|
|
|
import string as string_module
|
|
|
|
from yaql.language import specs
|
|
from yaql.language import utils
|
|
from yaql.language import yaqltypes
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_>')
|
|
def gt(left, right):
|
|
""":yaql:operator >
|
|
|
|
Returns true if the left operand is strictly greater than the right,
|
|
ordering lexicographically, otherwise false.
|
|
|
|
:signature: left > right
|
|
:arg left: left operand
|
|
:argType left: string
|
|
:arg right: right operand
|
|
:argType right: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "abc" > "ab"
|
|
true
|
|
yaql> "abc" > "abb"
|
|
true
|
|
yaql> "abc" > "abc"
|
|
false
|
|
"""
|
|
return left > right
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_<')
|
|
def lt(left, right):
|
|
""":yaql:operator <
|
|
|
|
Returns true if the left operand is strictly less than the right, ordering
|
|
lexicographically, otherwise false.
|
|
|
|
:signature: left < right
|
|
:arg left: left operand
|
|
:argType left: string
|
|
:arg right: right operand
|
|
:argType right: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "ab" < "abc"
|
|
true
|
|
yaql> "abb" < "abc"
|
|
true
|
|
yaql> "abc" < "abc"
|
|
false
|
|
"""
|
|
return left < right
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_>=')
|
|
def gte(left, right):
|
|
""":yaql:operator >=
|
|
|
|
Returns true if the left operand is greater or equal to the right, ordering
|
|
lexicographically, otherwise false.
|
|
|
|
:signature: left >= right
|
|
:arg left: left operand
|
|
:argType left: string
|
|
:arg right: right operand
|
|
:argType right: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "abc" >= "ab"
|
|
true
|
|
yaql> "abc" >= "abc"
|
|
true
|
|
"""
|
|
return left >= right
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_<=')
|
|
def lte(left, right):
|
|
""":yaql:operator <=
|
|
|
|
Returns true if the left operand is less or equal to the right, ordering
|
|
lexicographically, otherwise false.
|
|
|
|
:signature: left <= right
|
|
:arg left: left operand
|
|
:argType left: string
|
|
:arg right: right operand
|
|
:argType right: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "ab" <= "abc"
|
|
true
|
|
yaql> "abc" <= "abc"
|
|
true
|
|
"""
|
|
return left <= right
|
|
|
|
|
|
@specs.parameter('args', yaqltypes.String())
|
|
def concat(*args):
|
|
""":yaql:concat
|
|
|
|
Returns concatenated args.
|
|
|
|
:signature: concat([args])
|
|
:arg [args]: values to be joined
|
|
:argType [args]: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> concat("abc", "de", "f")
|
|
"abcdef"
|
|
"""
|
|
return ''.join(args)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.method
|
|
def to_upper(string):
|
|
""":yaql:toUpper
|
|
|
|
Returns a string with all case-based characters uppercase.
|
|
|
|
:signature: string.toUpper()
|
|
:receiverArg string: value to uppercase
|
|
:argType string: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "aB1c".toUpper()
|
|
"AB1C"
|
|
"""
|
|
return string.upper()
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.extension_method
|
|
def len_(string):
|
|
""":yaql:len
|
|
|
|
Returns size of the string.
|
|
|
|
:signature: string.len()
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:returnType: integer
|
|
|
|
.. code::
|
|
|
|
yaql> "abc".len()
|
|
3
|
|
"""
|
|
return len(string)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.method
|
|
def to_lower(string):
|
|
""":yaql:toLower
|
|
|
|
Returns a string with all case-based characters lowercase.
|
|
|
|
:signature: string.toLower()
|
|
:receiverArg string: value to lowercase
|
|
:argType string: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "AB1c".toLower()
|
|
"ab1c"
|
|
"""
|
|
return string.lower()
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('separator', yaqltypes.String(nullable=True))
|
|
@specs.parameter('max_splits', int)
|
|
@specs.method
|
|
def split(string, separator=None, max_splits=-1):
|
|
""":yaql:split
|
|
|
|
Returns a list of tokens in the string, using separator as the
|
|
delimiter.
|
|
|
|
:signature: string.split(separator => null, maxSplits => -1)
|
|
:receiverArg string: value to be splitted
|
|
:argType string: string
|
|
:arg separator: delimiter for splitting. null by default, which means
|
|
splitting with whitespace characters
|
|
:argType separator: string
|
|
:arg maxSplits: maximum number of splittings. -1 by default, which means
|
|
all possible splits are done
|
|
:argType maxSplits: integer
|
|
:returnType: list
|
|
|
|
.. code::
|
|
|
|
yaql> "abc de f".split()
|
|
["abc", "de", "f"]
|
|
yaql> "abc de f".split(maxSplits => 1)
|
|
["abc", "de f"]
|
|
yaql> "abcde".split("c")
|
|
["ab", "de"]
|
|
"""
|
|
return string.split(separator, max_splits)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('separator', yaqltypes.String(nullable=True))
|
|
@specs.parameter('max_splits', int)
|
|
@specs.method
|
|
def right_split(string, separator=None, max_splits=-1):
|
|
""":yaql:rightSplit
|
|
|
|
Returns a list of tokens in the string, using separator as the
|
|
delimiter. If maxSplits is given then at most maxSplits splits are done -
|
|
the rightmost ones.
|
|
|
|
:signature: string.rightSplit(separator => null, maxSplits => -1)
|
|
:receiverArg string: value to be splitted
|
|
:argType string: string
|
|
:arg separator: delimiter for splitting. null by default, which means
|
|
splitting with whitespace characters
|
|
:argType separator: string
|
|
:arg maxSplits: number of splits to be done - the rightmost ones.
|
|
-1 by default, which means all possible splits are done
|
|
:argType maxSplits: integer
|
|
:returnType: list
|
|
|
|
.. code::
|
|
|
|
yaql> "abc de f".rightSplit()
|
|
["abc", "de", "f"]
|
|
yaql> "abc de f".rightSplit(maxSplits => 1)
|
|
["abc de", "f"]
|
|
"""
|
|
return string.rsplit(separator, max_splits)
|
|
|
|
|
|
@specs.parameter('sequence', yaqltypes.Iterable())
|
|
@specs.parameter('separator', yaqltypes.String())
|
|
@specs.inject('str_delegate', yaqltypes.Delegate('str'))
|
|
@specs.method
|
|
def join(sequence, separator, str_delegate):
|
|
""":yaql:join
|
|
|
|
Returns a string with sequence elements joined by the separator.
|
|
|
|
:signature: sequence.join(separator)
|
|
:receiverArg sequence: chain of values to be joined
|
|
:argType sequence: sequence of strings
|
|
:arg separator: value to be placed between joined pairs
|
|
:argType separator: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> ["abc", "de", "f"].join("")
|
|
"abcdef"
|
|
yaql> ["abc", "de", "f"].join("|")
|
|
"abc|de|f"
|
|
"""
|
|
return separator.join(map(str_delegate, sequence))
|
|
|
|
|
|
@specs.parameter('sequence', yaqltypes.Iterable())
|
|
@specs.parameter('separator', yaqltypes.String())
|
|
@specs.inject('str_delegate', yaqltypes.Delegate('str'))
|
|
@specs.method
|
|
def join_(separator, sequence, str_delegate):
|
|
""":yaql:join
|
|
|
|
Returns a string with sequence elements joined by the separator.
|
|
|
|
:signature: separator.join(sequence)
|
|
:receiverArg separator: value to be placed between joined pairs
|
|
:argType separator: string
|
|
:arg sequence: chain of values to be joined
|
|
:argType sequence: sequence of strings
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "|".join(["abc", "de", "f"])
|
|
"abc|de|f"
|
|
"""
|
|
return join(sequence, separator, str_delegate)
|
|
|
|
|
|
@specs.parameter('value', nullable=True)
|
|
def str_(value):
|
|
""":yaql:str
|
|
|
|
Returns a string representation of the value.
|
|
|
|
:signature: str(value)
|
|
:arg value: value to be evaluated to string
|
|
:argType value: any
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> str(["abc", "de"])
|
|
"(u'abc', u'd')"
|
|
yaql> str(123)
|
|
"123"
|
|
"""
|
|
if value is None:
|
|
return 'null'
|
|
elif value is True:
|
|
return 'true'
|
|
elif value is False:
|
|
return 'false'
|
|
else:
|
|
return str(value)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('chars', yaqltypes.String(nullable=True))
|
|
@specs.method
|
|
def trim(string, chars=None):
|
|
""":yaql:trim
|
|
|
|
Returns a string with the leading and trailing chars removed.
|
|
|
|
:signature: string.trim(chars => null)
|
|
:receiverArg string: value to be trimmed
|
|
:argType string: string
|
|
:arg chars: symbols to be removed from input string. null by default,
|
|
which means trim is done with whitespace characters
|
|
:argType chars: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> " abcd ".trim()
|
|
"abcd"
|
|
yaql> "aababa".trim("a")
|
|
"bab"
|
|
"""
|
|
return string.strip(chars)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('chars', yaqltypes.String(nullable=True))
|
|
@specs.method
|
|
def trim_left(string, chars=None):
|
|
""":yaql:trimLeft
|
|
|
|
Returns a string with the leading chars removed.
|
|
|
|
:signature: string.trimLeft(chars => null)
|
|
:receiverArg string: value to be trimmed
|
|
:argType string: string
|
|
:arg chars: symbols to be removed from start of input string. null by
|
|
default, which means trim is done with whitespace characters
|
|
:argType chars: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> " abcd ".trimLeft()
|
|
"abcd "
|
|
yaql> "aababa".trimLeft("a")
|
|
"baba"
|
|
"""
|
|
return string.lstrip(chars)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('chars', yaqltypes.String(nullable=True))
|
|
@specs.method
|
|
def trim_right(string, chars=None):
|
|
""":yaql:trimRight
|
|
|
|
Returns a string with the trailing chars removed.
|
|
|
|
:signature: string.trimRight(chars => null)
|
|
:receiverArg string: value to be trimmed
|
|
:argType string: string
|
|
:arg chars: symbols to be removed from end of input string. null by
|
|
default, which means trim is done with whitespace characters
|
|
:argType chars: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> " abcd ".trimRight()
|
|
" abcd"
|
|
yaql> "aababa".trimRight("a")
|
|
"aabab"
|
|
"""
|
|
return string.rstrip(chars)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String(nullable=True))
|
|
@specs.parameter('chars', yaqltypes.String(nullable=True))
|
|
@specs.extension_method
|
|
def norm(string, chars=None):
|
|
""":yaql:norm
|
|
|
|
Returns a string with the leading and trailing chars removed.
|
|
If the resulting string is empty, returns null.
|
|
|
|
:signature: string.norm(chars => null)
|
|
:receiverArg string: value to be cut with specified chars
|
|
:argType string: string
|
|
:arg chars: symbols to be removed from the start and the end of input
|
|
string. null by default, which means norm is done with whitespace
|
|
characters
|
|
:argType chars: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> " abcd ".norm()
|
|
"abcd"
|
|
yaql> "aaaa".norm("a")
|
|
null
|
|
"""
|
|
if string is None:
|
|
return None
|
|
value = string.strip(chars)
|
|
return None if not value else value
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String(nullable=True))
|
|
@specs.parameter('trim_spaces', bool, alias='trim')
|
|
@specs.parameter('chars', yaqltypes.String(nullable=True))
|
|
@specs.extension_method
|
|
def is_empty(string, trim_spaces=True, chars=None):
|
|
""":yaql:isEmpty
|
|
|
|
Returns true if the string with removed leading and trailing chars is
|
|
empty.
|
|
|
|
:signature: string.isEmpty(trimSpaces => true, chars => null)
|
|
:receiverArg string: value to be checked for emptiness after trim
|
|
:argType string: string
|
|
:arg trimSpaces: true by default, which means string to be trimmed with
|
|
chars. false means checking whether input string is empty
|
|
:argType trimSpaces: boolean
|
|
:arg chars: symbols for trimming. null by default, which means trim is
|
|
done with whitespace characters
|
|
:argType chars: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "abaab".isEmpty(chars=>"ab")
|
|
true
|
|
yaql> "aba".isEmpty(chars=>"a")
|
|
false
|
|
"""
|
|
if string is None:
|
|
return True
|
|
if trim_spaces:
|
|
string = string.strip(chars)
|
|
return not string
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('old', yaqltypes.String())
|
|
@specs.parameter('new', yaqltypes.String())
|
|
@specs.parameter('count', int)
|
|
@specs.method
|
|
def replace(string, old, new, count=-1):
|
|
""":yaql:replace
|
|
|
|
Returns a string with first count occurrences of old replaced with new.
|
|
|
|
:signature: string.replace(old, new, count => -1)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg old: value to be replaced
|
|
:argType old: string
|
|
:arg new: replacement for old value
|
|
:argType new: string
|
|
:arg count: how many first replacements to do. -1 by default, which means
|
|
to do all replacements
|
|
:argType count: integer
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "abaab".replace("ab", "cd")
|
|
"cdacd"
|
|
"""
|
|
return string.replace(old, new, count)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('replacements', utils.MappingType)
|
|
@specs.parameter('count', int)
|
|
@specs.inject('str_func', yaqltypes.Delegate('str'))
|
|
@specs.method
|
|
@specs.name('replace')
|
|
def replace_with_dict(string, str_func, replacements, count=-1):
|
|
""":yaql:replace
|
|
|
|
Returns a string with all occurrences of replacements' keys replaced
|
|
with corresponding replacements' values.
|
|
If count is specified, only the first count occurrences of every key
|
|
are replaced.
|
|
|
|
:signature: string.replace(replacements, count => -1)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg replacements: dict of replacements in format {old => new ...}
|
|
:argType replacements: mapping
|
|
:arg count: how many first occurrences of every key are replaced. -1 by
|
|
default, which means to do all replacements
|
|
:argType count: integer
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "abc ab abc".replace({abc => xx, ab => yy})
|
|
"xx yy xx"
|
|
yaql> "abc ab abc".replace({ab => yy, abc => xx})
|
|
"yyc yy yyc"
|
|
yaql> "abc ab abc".replace({ab => yy, abc => xx}, 1)
|
|
"yyc ab xx"
|
|
"""
|
|
for key, value in replacements.items():
|
|
string = string.replace(str_func(key), str_func(value), count)
|
|
return string
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', int)
|
|
@specs.name('#operator_*')
|
|
def string_by_int(left, right, engine):
|
|
""":yaql:operator *
|
|
|
|
Returns string repeated count times.
|
|
|
|
:signature: left * right
|
|
:arg left: left operand
|
|
:argType left: string
|
|
:arg right: right operator, how many times repeat input string
|
|
:argType right: integer
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "ab" * 2
|
|
"abab"
|
|
"""
|
|
utils.limit_memory_usage(engine, (-right + 1, u''), (right, left))
|
|
return left * right
|
|
|
|
|
|
@specs.parameter('left', yaqltypes.String())
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_in')
|
|
def in_(left, right):
|
|
""":yaql:operator in
|
|
|
|
Returns true if there is at least one occurrence of left string in right.
|
|
|
|
:signature: left in right
|
|
:arg left: left operand, which occurrence is checked
|
|
:argType left: string
|
|
:arg right: right operand
|
|
:argType right: string
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "ab" in "abc"
|
|
true
|
|
yaql> "ab" in "acb"
|
|
false
|
|
"""
|
|
return left in right
|
|
|
|
|
|
@specs.parameter('left', int)
|
|
@specs.parameter('right', yaqltypes.String())
|
|
@specs.name('#operator_*')
|
|
def int_by_string(left, right, engine):
|
|
""":yaql:operator *
|
|
|
|
Returns string repeated count times.
|
|
|
|
:signature: left * right
|
|
:arg left: left operand, how many times repeat input string
|
|
:argType left: integer
|
|
:arg right: right operator
|
|
:argType right: string
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> 2 * "ab"
|
|
"abab"
|
|
"""
|
|
return string_by_int(right, left, engine)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('start', int)
|
|
@specs.parameter('length', int)
|
|
@specs.method
|
|
def substring(string, start, length=-1):
|
|
""":yaql:substring
|
|
|
|
Returns a substring beginning from start index ending with start+end index.
|
|
|
|
:signature: string.substring(start, length => -1)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg start: index for substring to start with
|
|
:argType start: integer
|
|
:arg length: length of substring. -1 by default, which means end of
|
|
substring to be equal to the end of input string
|
|
:argType length: integer
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> "abcd".substring(1)
|
|
"bcd"
|
|
yaql> "abcd".substring(1, 2)
|
|
"bc"
|
|
"""
|
|
if length < 0:
|
|
length = len(string)
|
|
if start < 0:
|
|
start += len(string)
|
|
return string[start:start + length]
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('sub', yaqltypes.String())
|
|
@specs.parameter('start', int)
|
|
@specs.method
|
|
def index_of(string, sub, start=0):
|
|
""":yaql:indexOf
|
|
|
|
Returns an index of first occurrence sub in string beginning from start.
|
|
-1 is a return value if there is no any occurrence.
|
|
|
|
:signature: string.indexOf(sub, start => 0)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg sub: substring to find in string
|
|
:argType sub: string
|
|
:arg start: index to start search with, 0 by default
|
|
:argType start: integer
|
|
:returnType: integer
|
|
|
|
.. code::
|
|
|
|
yaql> "cabcdab".indexOf("ab")
|
|
1
|
|
yaql> "cabcdab".indexOf("ab", 2)
|
|
5
|
|
yaql> "cabcdab".indexOf("ab", 6)
|
|
-1
|
|
"""
|
|
return string.find(sub, start)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('sub', yaqltypes.String())
|
|
@specs.parameter('start', int)
|
|
@specs.parameter('length', int)
|
|
@specs.method
|
|
def index_of_(string, sub, start, length):
|
|
""":yaql:indexOf
|
|
|
|
Returns an index of first occurrence sub in string beginning from start
|
|
ending with start+length.
|
|
-1 is a return value if there is no any occurrence.
|
|
|
|
:signature: string.indexOf(sub, start, length)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg sub: substring to find in string
|
|
:argType sub: string
|
|
:arg start: index to start search with, 0 by default
|
|
:argType start: integer
|
|
:arg length: length of string to find substring in
|
|
:argType length: integer
|
|
:returnType: integer
|
|
|
|
.. code::
|
|
|
|
yaql> "cabcdab".indexOf("bc", 2, 2)
|
|
2
|
|
"""
|
|
if start < 0:
|
|
start += len(string)
|
|
if length < 0:
|
|
length = len(string) - start
|
|
return string.find(sub, start, start + length)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('sub', yaqltypes.String())
|
|
@specs.parameter('start', int)
|
|
@specs.method
|
|
def last_index_of(string, sub, start=0):
|
|
""":yaql:lastIndexOf
|
|
|
|
Returns an index of last occurrence sub in string beginning from start.
|
|
-1 is a return value if there is no any occurrence.
|
|
|
|
:signature: string.lastIndexOf(sub, start => 0)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg sub: substring to find in string
|
|
:argType sub: string
|
|
:arg start: index to start search with, 0 by default
|
|
:argType start: integer
|
|
:returnType: integer
|
|
|
|
.. code::
|
|
|
|
yaql> "cabcdab".lastIndexOf("ab")
|
|
5
|
|
"""
|
|
return string.rfind(sub, start)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('sub', yaqltypes.String())
|
|
@specs.parameter('start', int)
|
|
@specs.parameter('length', int)
|
|
@specs.method
|
|
def last_index_of_(string, sub, start, length):
|
|
""":yaql:lastIndexOf
|
|
|
|
Returns an index of last occurrence sub in string beginning from start
|
|
ending with start+length.
|
|
-1 is a return value if there is no any occurrence.
|
|
|
|
:signature: string.lastIndexOf(sub, start, length)
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg sub: substring to find in string
|
|
:argType sub: string
|
|
:arg start: index to start search with, 0 by default
|
|
:argType start: integer
|
|
:arg length: length of string to find substring in
|
|
:argType length: integer
|
|
:returnType: integer
|
|
|
|
.. code::
|
|
|
|
yaql> "cabcdbc".lastIndexOf("bc", 2, 5)
|
|
5
|
|
"""
|
|
if start < 0:
|
|
start += len(string)
|
|
if length < 0:
|
|
length = len(string) - start
|
|
return string.rfind(sub, start, start + length)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.method
|
|
def to_char_array(string):
|
|
""":yaql:toCharArray
|
|
|
|
Converts a string to array of one character strings.
|
|
|
|
:signature: string.toCharArray()
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:returnType: list
|
|
|
|
.. code::
|
|
|
|
yaql> "abc de".toCharArray()
|
|
["a", "b", "c", " ", "d", "e"]
|
|
"""
|
|
return tuple(string)
|
|
|
|
|
|
def characters(
|
|
digits=False, hexdigits=False,
|
|
ascii_lowercase=False, ascii_uppercase=False,
|
|
ascii_letters=False, letters=False,
|
|
octdigits=False, punctuation=False, printable=False,
|
|
lowercase=False, uppercase=False, whitespace=False):
|
|
""":yaql:characters
|
|
|
|
Returns a list of all distinct items of specified types.
|
|
|
|
:signature: characters(digits => false, hexdigits => false,
|
|
asciiLowercase => false, asciiUppercase => false,
|
|
asciiLetters => false, letters => false,
|
|
octdigits => false, punctuation => false,
|
|
printable => false, lowercase => false,
|
|
uppercase => false, whitespace => false)
|
|
:arg digits: include digits in output list if true, false by default
|
|
:argType digits: boolean
|
|
:arg hexdigits: include hexademical digits in output list if true, false
|
|
by default
|
|
:argType hexdigits: boolean
|
|
:arg asciiLowercase: include ASCII lowercase letters in output list if
|
|
true, false by default
|
|
:argType asciiLowercase: boolean
|
|
:arg asciiUppercase: include ASCII uppercase letters in output list if
|
|
true, false by default
|
|
:argType asciiUppercase: boolean
|
|
:arg asciiLetters: include both ASCII lowercase and uppercase letters
|
|
in output list if true, false by default
|
|
:argType asciiLetters: boolean
|
|
:arg letters: include both lowercase and uppercase letters in output list
|
|
if true, false by default
|
|
:argType letters: boolean
|
|
:arg octdigits: include digits from 0 to 7 in output list if true, false
|
|
by default
|
|
:argType octdigits: boolean
|
|
:arg punctuation: include ASCII characters, which are considered
|
|
punctuation, in output list if true, false by default
|
|
:argType punctuation: boolean
|
|
:arg printable: include digits, letters, punctuation, and whitespace in
|
|
output list if true, false by default
|
|
:argType printable: boolean
|
|
:arg lowercase: include lowercase letters in output list if true, false
|
|
by default
|
|
:argType lowercase: boolean
|
|
:arg uppercase: include uppercase letters in output list if true, false
|
|
by default
|
|
:argType uppercase: boolean
|
|
:arg whitespace: include all characters that are considered whitespace
|
|
in output list if true, false by default
|
|
:argType whitespace: boolean
|
|
:returnType: list
|
|
|
|
.. code::
|
|
|
|
yaql> characters(digits => true)
|
|
["1", "0", "3", "2", "5", "4", "7", "6", "9", "8"]
|
|
|
|
"""
|
|
string = ''
|
|
if digits:
|
|
string += string_module.digits
|
|
if hexdigits:
|
|
string += string_module.hexdigits
|
|
if ascii_lowercase:
|
|
string += string_module.ascii_lowercase
|
|
if ascii_uppercase:
|
|
string += string_module.ascii_uppercase
|
|
if ascii_letters:
|
|
string += string_module.ascii_letters
|
|
if letters:
|
|
string += string_module.letters
|
|
if octdigits:
|
|
string += string_module.octdigits
|
|
if punctuation:
|
|
string += string_module.punctuation
|
|
if printable:
|
|
string += string_module.printable
|
|
if lowercase:
|
|
string += string_module.lowercase
|
|
if uppercase:
|
|
string += string_module.uppercase
|
|
if whitespace:
|
|
string += string_module.whitespace
|
|
return tuple(set(string))
|
|
|
|
|
|
def is_string(arg):
|
|
""":yaql:isString
|
|
|
|
Returns true if arg is a string.
|
|
|
|
:signature: isString(arg)
|
|
:arg arg: input value
|
|
:argType arg: any
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> isString("ab")
|
|
true
|
|
yaql> isString(1)
|
|
false
|
|
"""
|
|
return isinstance(arg, str)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('prefixes', yaqltypes.String())
|
|
@specs.method
|
|
def starts_with(string, *prefixes):
|
|
""":yaql:startsWith
|
|
|
|
Returns true if a string starts with any of given args.
|
|
|
|
:signature: string.startsWith([args])
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg [args]: chain of strings to check input string with
|
|
:argType [args]: strings
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "abcd".startsWith("ab", "xx")
|
|
true
|
|
yaql> "abcd".startsWith("yy", "xx", "zz")
|
|
false
|
|
"""
|
|
return string.startswith(prefixes)
|
|
|
|
|
|
@specs.parameter('string', yaqltypes.String())
|
|
@specs.parameter('suffixes', yaqltypes.String())
|
|
@specs.method
|
|
def ends_with(string, *suffixes):
|
|
""":yaql:endsWith
|
|
|
|
Returns true if a string ends with any of given args.
|
|
|
|
:signature: string.endsWith([args])
|
|
:receiverArg string: input string
|
|
:argType string: string
|
|
:arg [args]: chain of strings to check input string with
|
|
:argType [args]: strings
|
|
:returnType: boolean
|
|
|
|
.. code::
|
|
|
|
yaql> "abcd".endsWith("cd", "xx")
|
|
true
|
|
yaql> "abcd".endsWith("yy", "xx", "zz")
|
|
false
|
|
"""
|
|
return string.endswith(suffixes)
|
|
|
|
|
|
@specs.parameter('num', yaqltypes.Number(nullable=True))
|
|
def hex_(num):
|
|
""":yaql:hex
|
|
|
|
Returns a string with hexadecimal representation of num.
|
|
|
|
:signature: hex(num)
|
|
:arg num: input number to be converted to hexademical
|
|
:argType num: number
|
|
:returnType: string
|
|
|
|
.. code::
|
|
|
|
yaql> hex(256)
|
|
"0x100"
|
|
"""
|
|
return hex(num)
|
|
|
|
|
|
def register(context):
|
|
context.register_function(gt)
|
|
context.register_function(lt)
|
|
context.register_function(gte)
|
|
context.register_function(lte)
|
|
context.register_function(len_)
|
|
context.register_function(to_lower)
|
|
context.register_function(to_upper)
|
|
context.register_function(split)
|
|
context.register_function(right_split)
|
|
context.register_function(join)
|
|
context.register_function(join_)
|
|
context.register_function(str_)
|
|
context.register_function(concat)
|
|
context.register_function(concat, name='#operator_+')
|
|
context.register_function(trim)
|
|
context.register_function(trim_left)
|
|
context.register_function(trim_right)
|
|
context.register_function(replace)
|
|
context.register_function(replace_with_dict)
|
|
context.register_function(is_empty)
|
|
context.register_function(string_by_int)
|
|
context.register_function(int_by_string)
|
|
context.register_function(substring)
|
|
context.register_function(index_of)
|
|
context.register_function(index_of_)
|
|
context.register_function(last_index_of)
|
|
context.register_function(last_index_of_)
|
|
context.register_function(to_char_array)
|
|
context.register_function(characters)
|
|
context.register_function(is_string)
|
|
context.register_function(norm)
|
|
context.register_function(in_)
|
|
context.register_function(starts_with)
|
|
context.register_function(ends_with)
|
|
context.register_function(hex_)
|