#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
字符串工具函数
提供各种字符串操作的实用函数
所有函数均为异步实现
"""

import re
from typing import List, Optional, Union


async def is_blank(s: Optional[str]) -> bool:
    """
    检查字符串是否为None、空字符串或只包含空白字符
    
    Args:
        s: 要检查的字符串
        
    Returns:
        bool: 如果字符串为None、空字符串或只包含空白字符，则返回True；否则返回False
    """
    return s is None or (isinstance(s, str) and s.strip() == "")


async def is_not_blank(s: Optional[str]) -> bool:
    """
    检查字符串是否不为空（不为None且不只包含空白字符）
    
    Args:
        s: 要检查的字符串
        
    Returns:
        bool: 如果字符串不为None且不只包含空白字符，则返回True；否则返回False
    """
    return not await is_blank(s)


async def is_any_blank(*strings: Optional[str]) -> bool:
    """
    检查是否有任何一个字符串为空
    
    Args:
        *strings: 要检查的字符串列表
        
    Returns:
        bool: 如果任何一个字符串为空，则返回True；否则返回False
    """
    for s in strings:
        if await is_blank(s):
            return True
    return False


async def is_all_blank(*strings: Optional[str]) -> bool:
    """
    检查是否所有字符串都为空
    
    Args:
        *strings: 要检查的字符串列表
        
    Returns:
        bool: 如果所有字符串都为空，则返回True；否则返回False
    """
    for s in strings:
        if not await is_blank(s):
            return False
    return True


async def is_numeric(s: Optional[str]) -> bool:
    """
    检查字符串是否为数字（整数或浮点数）
    
    Args:
        s: 要检查的字符串
        
    Returns:
        bool: 如果字符串是数字，则返回True；否则返回False
    """
    if await is_blank(s):
        return False
    try:
        float(s)
        return True
    except (ValueError, TypeError):
        return False


async def is_alpha(s: Optional[str]) -> bool:
    """
    检查字符串是否只包含字母
    
    Args:
        s: 要检查的字符串
        
    Returns:
        bool: 如果字符串只包含字母，则返回True；否则返回False
    """
    if await is_blank(s):
        return False
    return isinstance(s, str) and s.isalpha()


async def starts_with(s: Optional[str], prefix: str) -> bool:
    """
    检查字符串是否以指定前缀开头
    
    Args:
        s: 要检查的字符串
        prefix: 前缀字符串
        
    Returns:
        bool: 如果字符串以指定前缀开头，则返回True；否则返回False
    """
    if await is_blank(s):
        return False
    return isinstance(s, str) and s.startswith(prefix)


async def ends_with(s: Optional[str], suffix: str) -> bool:
    """
    检查字符串是否以指定后缀结尾
    
    Args:
        s: 要检查的字符串
        suffix: 后缀字符串
        
    Returns:
        bool: 如果字符串以指定后缀结尾，则返回True；否则返回False
    """
    if await is_blank(s):
        return False
    return isinstance(s, str) and s.endswith(suffix)


async def contains(s: Optional[str], sub: str) -> bool:
    """
    检查字符串是否包含指定子字符串
    
    Args:
        s: 要检查的字符串
        sub: 子字符串
        
    Returns:
        bool: 如果字符串包含指定子字符串，则返回True；否则返回False
    """
    if await is_blank(s):
        return False
    return isinstance(s, str) and sub in s


async def split(s: Optional[str], sep: str, maxsplit: int = -1) -> List[str]:
    """
    按指定分隔符拆分字符串
    
    Args:
        s: 要拆分的字符串
        sep: 分隔符
        maxsplit: 最大拆分次数，默认为-1（无限制）
        
    Returns:
        List[str]: 拆分后的字符串列表
    """
    if await is_blank(s):
        return []
    return s.split(sep, maxsplit)


async def chop(s: Optional[str]) -> str:
    """
    去掉字符串的最后一个字符
    
    Args:
        s: 要处理的字符串
        
    Returns:
        str: 处理后的字符串，如果原字符串为空，则返回空字符串
    """
    if await is_blank(s):
        return ""
    return s[:-1]


async def chomp(s: Optional[str]) -> str:
    """
    去掉字符串末尾的换行符（\\n、\\r 或 \\r\\n）
    
    Args:
        s: 要处理的字符串
        
    Returns:
        str: 处理后的字符串，如果原字符串为空，则返回空字符串
    """
    if await is_blank(s):
        return ""
    if s.endswith("\r\n"):
        return s[:-2]
    if s.endswith("\n") or s.endswith("\r"):
        return s[:-1]
    return s


async def index_of(s: Optional[str], sub: str, start: int = 0, end: Optional[int] = None) -> int:
    """
    查找子字符串在字符串中的索引位置
    
    Args:
        s: 要搜索的字符串
        sub: 要查找的子字符串
        start: 开始搜索的位置，默认为0
        end: 结束搜索的位置，默认为None（搜索到字符串末尾）
        
    Returns:
        int: 子字符串在字符串中的索引位置，如果找不到则返回-1
    """
    if await is_blank(s) or await is_blank(sub):
        return -1
    try:
        return s.index(sub, start, end) if end else s.index(sub, start)
    except ValueError:
        return -1


async def difference(str1: Optional[str], str2: Optional[str]) -> str:
    """
    获取第二个字符串在第一个字符串中不一样的部分
    从第二个字符串第一位去匹配第一个字符串，按照顺序比较
    
    Args:
        str1: 第一个字符串
        str2: 第二个字符串
        
    Returns:
        str: 不一样的部分，如果任一字符串为空或无差异，则返回空字符串
    """
    if await is_blank(str1) or await is_blank(str2):
        return ""
    
    # 找到共同前缀的长度
    i = 0
    min_len = min(len(str1), len(str2))
    while i < min_len and str1[i] == str2[i]:
        i += 1
    
    # 如果第二个字符串比第一个短，或者完全匹配，则返回空字符串
    if i >= len(str2):
        return ""
    
    # 返回不同的部分
    return str2[i:]


async def replace(s: Optional[str], old: str, new: str, count: int = -1) -> str:
    """
    替换字符串中的指定子串
    
    Args:
        s: 原字符串
        old: 要替换的子串
        new: 替换后的子串
        count: 替换次数，默认为-1（全部替换）
        
    Returns:
        str: 替换后的字符串
    """
    if await is_blank(s):
        return ""
    return s.replace(old, new, count)


async def remove(s: Optional[str], sub: str) -> str:
    """
    从字符串中删除所有指定的子串
    
    Args:
        s: 原字符串
        sub: 要删除的子串
        
    Returns:
        str: 删除后的字符串
    """
    return await replace(s, sub, "")


async def right(s: Optional[str], length: int) -> str:
    """
    从右边获取指定长度的子字符串
    
    Args:
        s: 原字符串
        length: 要获取的长度
        
    Returns:
        str: 截取的子字符串
    """
    if await is_blank(s):
        return ""
    if length <= 0:
        return ""
    if length >= len(s):
        return s
    return s[-length:]


async def left(s: Optional[str], length: int) -> str:
    """
    从左边获取指定长度的子字符串
    
    Args:
        s: 原字符串
        length: 要获取的长度
        
    Returns:
        str: 截取的子字符串
    """
    if await is_blank(s):
        return ""
    if length <= 0:
        return ""
    return s[:length]


async def length(s: Optional[str]) -> int:
    """
    获取字符串的长度
    
    Args:
        s: 要测量的字符串
        
    Returns:
        int: 字符串的长度，如果为None则返回0
    """
    if s is None:
        return 0
    return len(s)


async def reverse(s: Optional[str]) -> str:
    """
    反转字符串
    
    Args:
        s: 要反转的字符串
        
    Returns:
        str: 反转后的字符串
    """
    if await is_blank(s):
        return ""
    return s[::-1] 