-
在Python中,可以通过编写函数实现驼峰命名法(CamelCase)与下划线命名法(snake_case)的相互转换。以下是两种转换的实现方法:1. 驼峰转下划线(CamelCase → snake_case)import re def camel_to_snake(name): # 在大写字母前插入下划线,然后转为小写 s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() # 示例 print(camel_to_snake("CamelCase")) # 输出: camel_case print(camel_to_snake("XMLParser")) # 输出: xml_parser 原理:使用正则表达式匹配大写字母前的位置,插入下划线。将所有字母转为小写。2. 下划线转驼峰(snake_case → CamelCase)小驼峰(首字母小写,如 camelCase):def snake_to_camel(name): components = name.split('_') return components[0] + ''.join(x.title() for x in components[1:]) # 示例 print(snake_to_camel("snake_case")) # 输出: snakeCase 大驼峰(首字母大写,如 CamelCase):def snake_to_pascal(name): return ''.join(x.title() for x in name.split('_')) # 示例 print(snake_to_pascal("snake_case")) # 输出: SnakeCase 原理:按下划线分割字符串。将每个单词的首字母大写(title()),然后拼接。小驼峰保留第一个单词的首字母小写。完整代码示例import re def camel_to_snake(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() def snake_to_camel(name): components = name.split('_') return components[0] + ''.join(x.title() for x in components[1:]) def snake_to_pascal(name): return ''.join(x.title() for x in name.split('_')) # 测试 print(camel_to_snake("CamelCase")) # camel_case print(snake_to_camel("snake_case")) # snakeCase print(snake_to_pascal("snake_case")) # SnakeCase 注意事项连续大写字母:如 XMLParser 会被转为 xml_parser(可能不符合某些规范,需根据需求调整)。数字处理:上述代码已支持带数字的命名(如 var1Name → var1_name)。性能:正则表达式适合大多数场景,但对超长字符串可能需优化。
-
在正则表达式中,\b 是一个**单词边界(word boundary)**的元字符,用于匹配单词的开始或结束位置,而不会消耗任何字符。它可以帮助你精确匹配完整的单词,避免匹配到部分内容。\b 的作用匹配单词边界(即 \w 和 \W 之间的位置):\w = [a-zA-Z0-9_](单词字符)\W = [^a-zA-Z0-9_](非单词字符)不消耗字符(零宽度断言),仅匹配位置。\b 的常见用法1. 匹配完整单词\bword\b匹配 "word",但不会匹配 "word123" 或 "sword"。示例:import re text = "hello world, word123, sword" matches = re.findall(r'\bword\b', text) print(matches) # 输出: ['word'](仅匹配独立的 "word") 2. 匹配单词开头\bword匹配 "word" 或 "word123",但不会匹配 "sword"。示例:matches = re.findall(r'\bword', text) print(matches) # 输出: ['word', 'word'](匹配 "word" 和 "word123" 的开头) 3. 匹配单词结尾word\b匹配 "word" 或 "sword",但不会匹配 "word123"。示例:matches = re.findall(r'word\b', text) print(matches) # 输出: ['word'](仅匹配 "word" 的结尾) 4. 匹配带标点的单词\bword\b[.,!?] 匹配 "word." 或 "word!" 等。示例:text = "hello world! word, word123" matches = re.findall(r'\bword\b[.,!?]?', text) print(matches) # 输出: ['word!'] \b vs. _b\b 是正则元字符,表示单词边界。_b 是普通字符串,匹配 "_b" 本身(如 "a_b" 或 "_b123")。错误示例:text = "a_b c_d" matches = re.findall(r'_b\b', text) # 错误!`_b` 不是单词边界 print(matches) # 输出: [](无法匹配) 正确写法:matches = re.findall(r'_b', text) # 匹配 "_b" 本身 print(matches) # 输出: ['_b'] 总结表达式含义\bword\b匹配完整单词 "word"\bword匹配以 "word" 开头的单词word\b匹配以 "word" 结尾的单词_b匹配字符串 "_b"(非正则边界)适用场景:用 \b 匹配完整单词(如搜索、替换)。用 _b 匹配字面 "_b"(如变量名、特定模式)。
-
在正则表达式中,?=、?<=、?!、?<! 是用于实现零宽度断言(Zero-Width Assertions)的语法,也被称为前瞻(Lookahead)和后瞻(Lookbehind)。它们允许你在不消耗字符(即不将匹配内容包含在结果中)的情况下,对匹配位置前后的文本进行条件判断。以下是它们的具体区别和使用场景:1. ?=(正向先行断言,Positive Lookahead)语法:A(?=B)含义:匹配 A,但仅当 A 后面紧跟着 B 时。B 不会被包含在匹配结果中。示例:正则表达式:\d(?=px)匹配:"5px" 中的 "5"(因为 "5" 后面是 "px")。不匹配:"5em" 中的 "5"(因为后面不是 "px")。用途:常用于匹配特定上下文中的字符,如单位、后缀等。2. ?!(负向先行断言,Negative Lookahead)语法:A(?!B)含义:匹配 A,但仅当 A 后面 不 紧跟着 B 时。B 不会被包含在匹配结果中。示例:正则表达式:\d(?!px)匹配:"5em" 中的 "5"(因为 "5" 后面不是 "px")。不匹配:"5px" 中的 "5"(因为后面是 "px")。用途:常用于排除特定上下文中的字符。3. ?<=(正向后行断言,Positive Lookbehind)语法:(?<=B)A含义:匹配 A,但仅当 A 前面是 B 时。B 不会被包含在匹配结果中。示例:正则表达式:(?<=\$)\d+匹配:"$100" 中的 "100"(因为 "100" 前面是 "$")。不匹配:"100" 中的 "100"(因为前面没有 "$")。用途:常用于匹配特定前缀后的字符,如货币符号后的数字。4. ?<!(负向后行断言,Negative Lookbehind)语法:(?<!B)A含义:匹配 A,但仅当 A 前面 不是 B 时。B 不会被包含在匹配结果中。示例:正则表达式:(?<!\$)\d+匹配:"100" 中的 "100"(因为 "100" 前面不是 "$")。不匹配:"$100" 中的 "100"(因为前面是 "$")。用途:常用于排除特定前缀后的字符。总结对比语法名称方向条件示例(匹配 "A" 的条件)?=正向先行断言向前后面是 B\d(?=px) → "5"(在 "5px" 中)?!负向先行断言向前后面不是 B\d(?!px) → "5"(在 "5em" 中)?<=正向后行断言向后前面是 B(?<=\$)\d+ → "100"(在 "$100" 中)?<!负向后行断言向后前面不是 B(?<!\$)\d+ → "100"(在 "100" 中)注意事项零宽度:这些断言不消耗字符,仅进行条件判断,因此匹配结果中不会包含 B。性能:复杂的断言可能影响正则表达式的性能,尤其是在处理长文本时。浏览器/引擎支持:大多数现代正则引擎(如 PCRE、JavaScript、Python 的 re 模块)都支持这些语法,但某些旧版本或简单实现可能不支持。实际应用示例匹配不以 http:// 开头的 URL:(?<!http://)\b\w+\.\w+\b匹配密码中的大写字母(但不包含在结果中):(?=.*[A-Z]).{6,} (这里 (?=.*[A-Z]) 确保密码中至少有一个大写字母,但实际匹配的是整个密码。)
-
在正则表达式中,限定符(Quantifiers) 用于指定前面的字符、字符组或子模式的重复次数。它们可以控制匹配的灵活性和范围,例如匹配“至少一个”、“零个或多个”、“恰好三次”等。一、常用限定符以下是正则表达式中最常用的限定符及其含义:限定符含义示例匹配结果*匹配前面的元素 0 次或多次(尽可能多匹配)a*"", "a", "aaa"+匹配前面的元素 1 次或多次(尽可能多匹配)a+"a", "aaa"(不匹配 "")?匹配前面的元素 0 次或 1 次(尽可能多匹配)a?"", "a"{n}匹配前面的元素 恰好 n 次a{3}"aaa"(不匹配 "a", "aa"){n,}匹配前面的元素 至少 n 次(尽可能多匹配)a{2,}"aa", "aaa"(不匹配 "a"){n,m}匹配前面的元素 至少 n 次,最多 m 次(尽可能多匹配)a{2,4}"aa", "aaa", "aaaa"二、限定符的贪婪与非贪婪模式默认情况下,限定符是贪婪的(Greedy),即尽可能多地匹配字符。如果希望尽可能少地匹配(非贪婪模式),可以在限定符后加 ?。模式示例贪婪匹配非贪婪匹配*a.*b"aabab" → 匹配 "aabab""aabab" → 匹配 "aab"+a.+b"aabab" → 匹配 "aabab""aabab" → 匹配 "aab"?a.?b"aab" → 匹配 "aab""aab" → 匹配 "ab"{n,m}a.{2,4}b"aaabbb" → 匹配 "aaabbb""aaabbb" → 匹配 "aaab"示例对比贪婪模式 a.*b 匹配 "aabab" → "aabab"(尽可能多匹配)非贪婪模式 a.*?b 匹配 "aabab" → "aab"(尽可能少匹配)三、限定符的适用范围限定符可以应用于:单个字符:a* # 匹配 0 个或多个 "a" 字符组:[abc]+ # 匹配 1 个或多个 "a"、"b" 或 "c" 子模式(分组):(ab)+ # 匹配 1 个或多个 "ab"(如 "ab", "abab")转义字符:\d{3} # 匹配 3 个数字(如 "123")四、常见用例1. 匹配数字\d+ → 匹配 1 个或多个数字(如 "123")\d{4} → 匹配恰好 4 位数字(如 "2023")\d{2,4} → 匹配 2 到 4 位数字(如 "42", "1234")2. 匹配 URL 路径^/articles/([a-z0-9-]+)/?$ # 匹配 "/articles/some-title/" 或 "/articles/some-title" [a-z0-9-]+ → 匹配 1 个或多个字母、数字或连字符/? → 可选斜杠(0 次或 1 次)3. 匹配 HTML 标签<img[^>]*> # 匹配 <img> 标签及其属性(非贪婪模式更安全)[^>]* → 匹配 0 个或多个非 > 字符4. 匹配重复单词\b(\w+)\s+\1\b # 匹配重复单词(如 "hello hello")(\w+) → 捕获一个单词\s+ → 1 个或多个空白符\1 → 引用第一个捕获组(即重复的单词)五、不同编程语言中的限定符大多数编程语言(如 Python、JavaScript、Java、Perl、PHP)的正则引擎都支持上述限定符,但细节可能略有不同:语言示例说明Pythonre.findall(r'\d{3}-\d{4}', '123-4567')使用 r 前缀避免转义问题JavaScript'aabb'.match(/a{2}b{2}/)直接使用 /.../ 语法JavaPattern.compile("\\d{3}-\\d{4}")需要双重转义 \\Perl'aabb' =~ /a+b+/直接匹配,无需编译六、常见问题Q1: 为什么 .* 会匹配整个字符串?.* 是贪婪模式,会尽可能多地匹配字符(直到字符串末尾)。如果希望匹配到第一个匹配项,应使用非贪婪模式 .*?。Q2: 如何匹配“至少一个数字或字母”?使用字符组 + 限定符:[0-9a-zA-Z]+ # 匹配 1 个或多个数字或字母Q3: 如何匹配“最多 3 个连续空格”?使用 {0,3}:\s{0,3} # 匹配 0 到 3 个空格Q4: 为什么 a{3,} 不匹配 "aa"?a{3,} 要求至少 3 个 "a",而 "aa" 只有 2 个,因此不匹配。七、总结限定符 控制字符、字符组或子模式的重复次数。贪婪模式(默认)尽可能多匹配,非贪婪模式(加 ?)尽可能少匹配。常用限定符:*, +, ?, {n}, {n,}, {n,m}。适用于单个字符、字符组、子模式和转义字符。不同编程语言语法基本一致,但需注意转义规则(如 Java 需要 \\)。掌握限定符后,可以更灵活地控制正则表达式的匹配范围! 🚀
-
在正则表达式中,非打印字符(Non-Printing Characters)是指那些不可见但具有特殊功能的字符,如换行符、制表符、回车符等。这些字符通常需要通过转义序列(Escape Sequences)来表示,以便在正则中精确匹配它们。一、常见的非打印字符转义序列以下是正则表达式中常用的非打印字符转义序列:转义序列含义ASCII 码示例\t制表符(Tab)\x09"a\tb" → "a b"(中间是Tab)\n换行符(Line Feed)\x0A"Hello\nWorld" → 两行文本\r回车符(Carriage Return)\x0D旧式 Mac 换行(\r\n 是 Windows 换行)\f换页符(Form Feed)\x0C打印机换页(较少使用)\a响铃符(Bell)\x07终端响铃(极少使用)\e转义符(Escape)\x1BANSI 转义序列(如终端颜色)\v垂直制表符(Vertical Tab)\x0B垂直方向制表(较少使用)\xHH十六进制转义(2位)HH\x20 → 空格(\x41 → 'A')\uHHHHUnicode 转义(4位,仅某些引擎支持)HHHH\u0041 → 'A'(仅支持 Unicode 的引擎)\cX控制字符(Control Character)Ctrl+X\cJ → 换行符(等价于 \n)二、使用示例1. 匹配制表符 \t\t+ # 匹配一个或多个制表符示例:匹配 "Name\tAge\tGender" 中的制表符分隔的字段。2. 匹配换行符 \n\r?\n # 匹配 Windows(\r\n)或 Unix(\n)换行示例:匹配多行文本中的换行符(如日志文件)。3. 匹配空白行(连续换行符)(?:\r?\n){2,} # 匹配两个或更多换行符(表示空行)4. 匹配 Windows 换行符 \r\n\r\n # 严格匹配 Windows 换行5. 匹配 Unicode 字符(如中文)[\u4e00-\u9fa5] # 匹配常见中文字符(仅支持 Unicode 的引擎,如 PCRE、Python、JavaScript)示例:匹配 "你好" 中的 "你" 或 "好"。三、不同编程语言中的注意事项JavaScript:支持 \n, \r, \t, \f, \v,但不支持 \a 或 \e。Unicode 字符需用 \uXXXX(如 \u4e00)。Python:支持 \n, \r, \t, \f, \v, \a, \e。原始字符串(r"\n")可避免转义冲突。Java:支持 \n, \r, \t, \f, \a, \e。Unicode 字符可用 \uXXXX 或 \x{HHHH}(需开启 UNICODE_CHARACTER_CLASS)。Perl / PCRE:支持所有常见转义序列,包括 \a, \e, \cX。支持 \x{HHHH} 扩展十六进制转义。.NET:支持 \n, \r, \t, \f, \v, \a, \e。支持 \uXXXX 和 \xHHHH。四、常见问题Q1: 为什么 \s 不匹配所有空白字符?\s 匹配 [ \t\n\r\f\v](包括空格、制表符、换行符等),但不匹配非换行空白符(如 \x0B)。如果需要精确匹配,建议直接使用 \t、\n 等转义序列。Q2: 如何匹配 Unicode 空白字符?某些引擎(如 PCRE)支持 \p{Z} 匹配所有 Unicode 空白字符。否则,需手动指定范围(如 [\u2000-\u200B\u3000])。Q3: 为什么 \x20 不匹配空格?\x20 是十六进制表示的空格(ASCII 32),等价于直接写空格或 \s(但 \s 还匹配其他空白符)。五、总结非打印字符(如 \t, \n, \r)在正则中需用转义序列表示。不同引擎支持情况不同(如 \a, \e 在某些引擎中可能无效)。Unicode 字符需用 \uXXXX(如 \u4e00 匹配中文)。原始字符串(如 Python 的 r"\n")可避免转义冲突。
-
在正则表达式中,特殊字符(也称为元字符)是具有特殊含义的字符,用于定义匹配规则。它们与普通字符(如字母、数字)不同,需要通过转义(通常加反斜杠 \)来表示其字面意义。以下是正则表达式中常见的特殊字符及其用法:一、基础特殊字符字符含义示例.匹配任意单个字符(除换行符 \n,除非启用 DOTALL 模式)。a.c → “abc”, “a1c”, “a c”^匹配字符串的开头(或在字符组 [] 内表示否定)。^Hello → 以 “Hello” 开头的字符串$匹配字符串的结尾。world$ → 以 “world” 结尾的字符串*匹配前面的元素0次或多次。ab*c → “ac”, “abc”, “abbc”+匹配前面的元素1次或多次。go+l → “gol”, “gool”, “gooool”?匹配前面的元素0次或1次(或表示非贪婪模式的修饰符)。colou?r → “color” 或 “colour”``表示逻辑或(匹配左边或右边的表达式)。二、字符组(Character Classes)字符含义示例[ ]匹配括号内的任意一个字符。[abc] → “a”, “b”, 或 “c”[^ ]匹配不在括号内的任意一个字符(否定字符组)。[^0-9] → 非数字字符[a-z]匹配小写字母范围(可组合使用)。[a-zA-Z0-9] → 字母或数字\d匹配数字(等价于 [0-9])。\d{3} → “123”, “456”\D匹配非数字(等价于 [^0-9])。\D+ → “abc”, “!@#”\w匹配单词字符(字母、数字、下划线,等价于 [a-zA-Z0-9_])。\w+ → “Java”, “hello_123”\W匹配非单词字符(等价于 [^\w])。\W+ → " ", “-”, “@”\s匹配空白字符(空格、制表符 \t、换行符 \n 等)。\s+ → " \t\n"\S匹配非空白字符(等价于 [^\s])。\S+ → “Hello”, “123”三、量词(Quantifiers)字符含义示例{n}匹配前面的元素恰好 n 次。\d{4} → “2023”{n,}匹配前面的元素至少 n 次。\d{2,} → “10”, “123”, “1000”{n,m}匹配前面的元素至少 n 次,最多 m 次。\d{2,4} → “12”, “123”, “1234”*等价于 {0,}(0次或多次)。ab*c → “ac”, “abc”, “abbc”+等价于 {1,}(1次或多次)。go+l → “gol”, “gool”?等价于 {0,1}(0次或1次)。colou?r → “color” 或 “colour”四、边界匹配(Anchors)字符含义示例^匹配字符串的开头(或在多行模式下匹配行的开头)。^Hello → “Hello…”$匹配字符串的结尾(或在多行模式下匹配行的结尾)。world$ → “…world”\b匹配单词边界(即单词与非单词字符之间的位置)。\bcat\b → “cat”(不匹配 “category”)\B匹配非单词边界。\Bcat\B → “scatter” 中的 “cat”五、分组与引用字符含义示例( )捕获分组:将多个字符视为一个单元,并记住匹配的文本(可通过 \1, \2 引用)。(ab)+ → “ab”, “abab”(?: )非捕获分组:分组但不记住匹配的文本(性能更高)。(?:ab)+ → 同上,但不捕获分组\n引用第 n 个捕获分组(n 为 1-9 的数字)。(\d)\1 → “11”, “22”(匹配重复数字)六、转义字符如果需要匹配特殊字符本身的字面值(而非其特殊含义),需用反斜杠 \ 转义:字符转义后含义示例\.匹配字面意义的点号 .192\.168\.1\.1 → “192.168.1.1”\\匹配字面意义的反斜杠 \C:\\Users\\ → “C:\Users”\*匹配字面意义的星号 *a\*b → “a*b”七、高级特殊字符字符含义示例?=正向预查:匹配后面跟着指定模式的字符串(不消耗字符)。foo(?=bar) → “foobar” 中的 “foo”?!负向预查:匹配后面不跟着指定模式的字符串。foo(?!bar) → “foobaz” 中的 “foo”?<=正向回顾后发:匹配前面是指定模式的字符串(不消耗字符)。(?<=foo)bar → “foobar” 中的 “bar”?<!负向回顾后发:匹配前面不是指定模式的字符串。(?<!foo)bar → “hellobar” 中的 “bar”八、常见正则表达式示例匹配邮箱地址:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$匹配URL:https?://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*) 匹配手机号(中国):^1[3-9]\d{9}$提取HTML标签:<([a-z]+)([^<]+)*(?:>(.*?)<\/\1>|\s+\/>) 总结特殊字符是正则表达式的核心,通过组合它们可以构建复杂的匹配规则。转义是关键:若需匹配字面意义的特殊字符(如 .、*),需用 \ 转义。分组与引用可用于提取或重复匹配子模式。预查和回顾后发用于更精确的上下文匹配(如“匹配后面跟着X的Y”)。
-
在正则表达式中,*、? 和 + 都是量词(Quantifiers),用于指定前面字符或组的匹配次数。以下是它们的详细解释和对比:1. *(星号)含义:匹配前面的字符或组 0 次或多次(即“可有可无,但可以有多个”)。示例:正则:ab*c匹配:ac(b 出现 0 次)、abc(b 出现 1 次)、abbbc(b 出现多次)。不匹配:ab(缺少结尾的 c)、aabc(b 前面不能有 a)。正则:\d*(匹配 0 个或多个数字)匹配:""(空)、"1"、"123"。2. ?(问号)含义:匹配前面的字符或组 0 次或 1 次(即“可有可无,但最多 1 个”)。示例:正则:ab?c匹配:ac(b 出现 0 次)、abc(b 出现 1 次)。不匹配:abbc(b 出现多次)。正则:colou?r(匹配英式/美式拼写)匹配:color(u 出现 0 次)、colour(u 出现 1 次)。特殊用法:非贪婪匹配当 ? 跟在 *、+ 或 ? 后面时(如 *?、+?、??),表示非贪婪匹配(尽量少匹配)。示例:import re text = "<div>hello</div><div>world</div>" greedy = re.search(r'<div>.*</div>', text) # 匹配整个字符串(贪婪) lazy = re.search(r'<div>.*?</div>', text) # 仅匹配第一个 `<div>hello</div>` 3. +(加号)含义:匹配前面的字符或组 1 次或多次(即“至少出现 1 次”)。示例:正则:ab+c匹配:abc(b 出现 1 次)、abbbc(b 出现多次)。不匹配:ac(b 出现 0 次)。正则:\d+(匹配 1 个或多个数字)匹配:"1"、"123"。不匹配:""(空)。对比总结量词匹配次数示例匹配 "abbc"匹配 "ac"*0 次或多次ab*c✅ (b 出现 2 次)✅ (b 出现 0 次)?0 次或 1 次ab?c❌ (b 出现 2 次)✅ (b 出现 0 次)+1 次或多次ab+c✅ (b 出现 2 次)❌ (b 出现 0 次)常见用途*:匹配可能不存在的模式(如可选的前缀/后缀)。示例:"*optional*" 可以匹配 "optional" 或 "*optional*"。?:匹配可选字符(如英式/美式拼写差异)。示例:"neighbou?r" 匹配 "neighbor" 或 "neighbour"。+:确保某个模式至少出现一次(如数字、字母)。示例:"\d+" 匹配 "123",但不匹配 ""。高级用法(1) 指定具体次数 {n,m}{n}:匹配 exactly n 次。{n,}:匹配至少 n 次。{n,m}:匹配 n 到 m 次。示例:a{3} → "aaa"a{2,4} → "aa"、"aaa"、"aaaa"(2) 非贪婪匹配 *?、+?、??默认情况下,*、+、? 是贪婪的(匹配尽可能多的字符)。加上 ? 后变为非贪婪(匹配尽可能少的字符)。示例:text = "<div>hello</div><div>world</div>" re.findall(r'<div>.*</div>', text) # 贪婪匹配 → `['<div>hello</div><div>world</div>']` re.findall(r'<div>.*?</div>', text) # 非贪婪匹配 → `['<div>hello</div>', '<div>world</div>']` 总结量词匹配次数非贪婪模式*0 次或多次*??0 次或 1 次??+1 次或多次+?* 最宽松(可有可无,可多个)。? 最严格(最多 1 个)。+ 折中(至少 1 个)。
-
1. 问题说明(一)模态页切换无过渡,体验生硬点击 “其他登录方式” 切换页面时,无动画过渡,页面跳转突兀,用户感知割裂,不符合流畅交互预期,影响使用体验。(二)多登录方式返回键逻辑复杂一键登录与其他登录方式需分别实现返回功能,未统一管理,易出现返回逻辑冲突(如误关闭模态页),增加开发调试成本。(三)协议未勾选仍可触发登录未校验 “服务协议” 勾选状态,用户未同意协议时点击 “一键登录”,无提示直接执行登录逻辑,不符合合规要求与交互逻辑。(四)手机号未达标,按钮状态不变手机号输入框未输入 11 位数字时,“发送验证码” 按钮仍为灰色不可用状态,但无明确反馈,用户不知需输入完整手机号。2. 原因分析(一)过渡效果缺失未为登录方式切换的组件设置transition属性,组件显隐时无系统动画支持,导致切换过程生硬,缺乏视觉连贯性。(二)返回键未统一布局未使用Stack等容器组件统一包裹不同登录页面,返回键需在每个页面单独实现,无法复用逻辑,易出现跳转逻辑混乱。(三)协议校验逻辑缺失登录按钮的onClick事件未添加 “协议勾选状态” 判断条件,未区分isAgree为false的场景,直接执行登录操作,无异常提示。(四)输入监听未绑定未为手机号输入框添加内容长度监听,未将输入长度与按钮enabled状态关联,无法动态激活按钮,缺乏用户引导。3. 解决思路(一)模态页绑定与过渡优化用bindContentCover绑定全屏模态页,通过transition设置滑入滑出效果,让模态页显隐与登录方式切换更流畅。(二)统一返回键布局用Stack组件包裹所有登录页面,将返回键置于顶层,复用返回逻辑,避免重复实现,解决跳转冲突问题。(三)协议勾选校验在登录按钮点击事件中,先判断协议勾选状态,未勾选时提示用户,勾选后再执行登录逻辑,确保合规与交互正确。(四)输入框与按钮联动监听手机号输入框内容变化,当输入长度达 11 位时,动态激活 “发送验证码” 按钮,同时提示用户,提升操作引导性。4. 解决方案(一)模态页绑定与显隐控制通过bindContentCover绑定模态页,控制显隐状态,实现从下方滑出的全屏效果: import { LoginModel } from './LoginModel'; @Builder export function PageThreeBuilder() { ModalWindowComponent() } @Component export struct ModalWindowComponent { // 是否显示全屏模态页面 @State isPresent: boolean = false; pathStack: NavPathStack = new NavPathStack(); @Builder loginBuilder() { Column() { // 通过@State和@Link使isPresentInLoginView和isPresent产生关联 LoginModel({ isPresentInLoginView: this.isPresent }) } } build() { NavDestination() { Column() { // TODO:需求:增加其他登录方式,如半模态窗口 Button('点击跳转到全屏登录页') .fontColor(Color.White) .borderRadius(8) .type(ButtonType.Normal) .backgroundColor('#222222') .width('100%') .bindContentCover($$this.isPresent, this.loginBuilder) .onClick(() => { this.isPresent = true; // 当isPresent为true时显示模态页面,反之不显示 }) } .size({ width:'100%', height: '100%' }) .padding(12) .justifyContent(FlexAlign.Center) } .title('Login_Model') .onReady((context: NavDestinationContext) => { this.pathStack = context.pathStack }) } } (二)登录方式切换(带过渡效果)用if-else条件渲染登录方式,通过transition添加滑入过渡:import promptAction from '@ohos.promptAction'; import { OtherWaysToLogin, ReadAgreement } from './OtherWaysToLogin'; const EFFECT_DURATION = 800; const EFFECT_OPACITY = 0.4; const SPACE_TEN = 10; @Component export struct LoginModel { @Link isPresentInLoginView: boolean; // 是否是默认一键登录方式 @State isDefaultLogin: boolean = true; // 用户名 userName: string = '18888888888'; // 判断是否同意协议 isConfirmed: boolean = false; private effect: TransitionEffect = TransitionEffect.OPACITY .animation({ duration: EFFECT_DURATION }) .combine(TransitionEffect.opacity(EFFECT_OPACITY)) // 默认一键登录方式 @Builder DefaultLoginPage() { Column({ space: SPACE_TEN }) { Row({ space: SPACE_TEN }) { Image('') .width(40) .height(40) Column({ space: SPACE_TEN }) { Text('Hi, 欢迎回来') .fontWeight(FontWeight.Bold) .fontSize(20) .fontColor(Color.Black) Text('登录后更精彩,美好生活即将开始') .fontColor('#333333') } .alignItems(HorizontalAlign.Start) } .alignItems(VerticalAlign.Center) .width('100%') Text(this.userName) .fontColor('#333333') .fontWeight(FontWeight.Bold) .padding({ left: 12 }) .height(40) .width('100%') .borderRadius(8) .backgroundColor('#eeeeeee') Text('认证服务由xxxx提供') .fontColor('#666666') .width('100%') .textAlign(TextAlign.Start) Row() { Checkbox({ name: 'checkbox1' }) .id('default_agreement') .select(this.isConfirmed) .onChange((value: boolean) => { this.isConfirmed = value }) ReadAgreement() } .width('100%') .alignItems(VerticalAlign.Center) Button('手机号码一键登录') .fontColor(Color.White) .borderRadius(8) .type(ButtonType.Normal) .backgroundColor('#222222') .onClick(() => { if (this.isConfirmed) { // 调用Toast显示登录成功提示 promptAction.showToast({ message: '登录成功' }); } else { // 调用Toast显示请先阅读并同意协议提示 promptAction.showToast({ message: '请先阅读并同意协议' }); } }) .width('100%') .height(50) Row() { Text('其他登录方式') .fontColor('#777777') .backgroundColor('#007777') .onClick(() => { this.isDefaultLogin = false; }) // 在容器主轴方向上自动填充容器空余部分 Blank() Text('遇到问题') .fontColor('#777777') .backgroundColor('#007777') .onClick(() => { // 调用Toast显示遇到问题提示 promptAction.showToast({ message:'遇到问题' }); }) } .width('100%') } .width('100%') .height('100%') .backgroundColor(Color.White) .justifyContent(FlexAlign.Center) } build() { Stack({ alignContent: Alignment.TopStart }) { // 登录方式有两种(默认一键登录方式和其他方式登录),需要在一个模态窗口中切换,使用if进行条件渲染 if (this.isDefaultLogin) { // 默认一键登录方式 this.DefaultLoginPage() } else { // 其他登录方式 OtherWaysToLogin() .transition(this.effect) // 此处涉及到组件的显示和消失,所以使用transition属性设置出现/消失转场 } Image($r('app.media.arrow_back'))// 通过Stack组件,两个页面只实现一个back .id('login_back') .width(25).height(25) .margin({ top: 20 }) .onClick(() => { if (this.isDefaultLogin) { this.isPresentInLoginView = false; } else { this.isDefaultLogin = true } }) } .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) .size({ width:'100%', height: '100%' }) .padding({ top: 12, left:12, right:12 }) .backgroundColor(Color.White) // 将模态页面背景设置为白色,以避免模态页面内组件发生显隐变化时露出下层页面 } } (三)统一返回键布局(Stack 组件)用Stack包裹登录内容,复用返回键逻辑(完整代码在上方Step2): Stack({ alignContent: Alignment.TopStart }) { // 登录方式有两种(默认一键登录方式和其他方式登录),需要在一个模态窗口中切换,使用if进行条件渲染 if (this.isDefaultLogin) { this.DefaultLoginPage() // 默认一键登录方式 } else { OtherWaysToLogin()// 其他登录方式 .transition(this.effect) // 此处涉及到组件的显示和消失,所以使用transition属性设置出现/消失转场 } Image($r('app.media.arrow_back'))// 通过Stack组件,两个页面只实现一个back .id('login_back') .width(25).height(25) .margin({ top: 20 }) .onClick(() => { if (this.isDefaultLogin) { this.isPresentInLoginView = false; } else { this.isDefaultLogin = true } }) } .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) .size({ width:'100%', height: '100%' }) .padding({ top: 12, left:12, right:12 }) .backgroundColor(Color.White) // 将模态页面背景设置为白色,以避免模态页面内组件发生显隐变化时露出下层页面 (四)协议勾选校验与登录控制添加协议勾选状态判断,未勾选时提示:@Component export struct ReadAgreement { build() { Text() { Span('阅读并同意') .fontColor('#999999') Span('服务协议及个人信息处理规则') .fontColor(Color.Orange) .onClick(() => { // 调用Toast显示用户点击服务协议及个人信息处理规则的提示 promptAction.showToast({ message: '服务协议及个人信息处理规则' }); }) } .textAlign(TextAlign.Start) } } (五)手机号输入与验证码按钮控制监听手机号输入长度,动态激活按钮:import { Prompt } from '@kit.ArkUI'; const PHONE_NUMBER_LENGTH = 11; const SPACE_TWENTY = 20; const SPACE_TEN = 10; const COUNTDOWN_SECONDS = 30; // 倒计时总秒数 const SEND_AGAIN_IN_SECONDS = "s后可再次发送"; @Component struct OtherLoginView { @State phoneNum: string = ''; // 手机号输入值 controller: TextInputController = new TextInputController(); // 发送验证码按钮的颜色 @State buttonColor: ResourceColor = Color.Grey; // 发送验证码按钮的内容 @State buttonContent: ResourceStr = '发送短信验证码'; // 手机号是否可用 phoneNumberAvailable: boolean = false; // 可发送验证码的倒计时秒数 build() { Column() { // 手机号输入框 TextInput({ placeholder:'请输入手机号' }) // 正则表达式,输入的是数字0-9则允许显示,不是则被过滤 .inputFilter('[0-9]') .backgroundColor(Color.Transparent) .caretColor(Color.Grey) .width('100%') .maxLength(PHONE_NUMBER_LENGTH)// 设置最大输入字符数 // 当输入字符数为11位时,发送验证码按钮变为蓝色,否则置灰 .onChange((value: string) => { if (value.length === PHONE_NUMBER_LENGTH) { this.phoneNumberAvailable = true; this.buttonColor = Color.Blue; } else { this.phoneNumberAvailable = false; this.buttonColor = Color.Grey; } }) } Button(this.buttonContent) .type(ButtonType.Normal) .border({ radius: 8 }) .width('100%') .backgroundColor(this.buttonColor) .id('send_button_id') .onClick(() => { if (this.countdownSeconds > 0) { // 处于可再次发送的读秒倒计时状态下,点击按钮不响应 return; } // 输入输入字符数为11位,并同意服务协议及个人信息处理规则,才能发送验证码 if (!this.phoneNumberAvailable) { promptAction.showToast({ message:'请输入正确的手机号' }); } else if (!this.isAgree) { promptAction.showToast({ message: '请先阅读并同意服务协议及个人信息处理规则' }); } else { // 点击发送短信验证码按钮后,按钮置灰,开始读秒倒计时,按钮内容改变 promptAction.showToast({ message: '验证码已发送') }); this.buttonColor = Color.Grey; this.countdownSeconds = COUNTDOWN_SECONDS; const timerId = setInterval(() => { this.countdownSeconds--; if (this.countdownSeconds <= 0) { // 计时结束,根据手机号位数是否正确,重置按钮状态 this.buttonContent = '发送短信验证码'; clearInterval(timerId); this.buttonColor = this.phoneNumberAvailable ? Color.Blue : Color.Grey; return; } this.buttonContent = this.countdownSeconds + SEND_AGAIN_IN_SECONDS; }, 1000) } }) } .padding(20) .width('100%') } } 5.方案成果总结 主页面点击触发下方滑出的全屏模态登录页,支持一键登录与其他登录方式切换。技术上通过 bindContentCover 绑定模态页,Stack 组件统一返回键逻辑避免跳转冲突,transition 添加页面切换过渡效果;还实现协议勾选校验(未勾选提示 “请先同意协议”)、手机号输入 11 位后激活 “发送验证码” 按钮等交互。案例复用组件减少冗余,功能合规且操作引导清晰,大幅提升登录交互流畅度,满足登录场景的使用需求与用户体验要求。
-
这个正则表达式是用于匹配特定的SQL语句,特别是SELECT语句,并且确保这个语句不包含INSERT、DELETE或UPDATE等可能修改数据的关键词。现在我会逐一解释这个正则表达式的各个部分:**^**:匹配字符串的开始。**(?i)**:这是一个模式修饰符,表示接下来的匹配应该是大小写不敏感的。但在你的正则中,SELECT和insert|delete|update等关键词已经是全部大写了,所以这个修饰符可能在这个特定场景中不是必需的,除非你还期望匹配到如select、Insert等大小写混合的关键词。**(\s*)**:匹配零个或多个空白字符(如空格、制表符、换行符等),并将这些字符捕获为一个组。**(\s+)**:再次匹配一个或多个空白字符,但这次它们是作为一个独立的捕获组。这意味着SELECT关键词之前和之后至少有一个空白字符。**select**:匹配字符串"select"(由于前面的(?i)修饰符,它也会匹配"Select"、"SELECT"等)。**(((?!(insert|delete|update)).)+)**:这是一个复杂的部分,我会逐步解释:**(?!(insert|delete|update))**:这是一个否定前瞻断言。它确保接下来的字符不是insert、delete或update中的任何一个。注意,由于(?i)修饰符,这个否定也会应用到大小写。**.**:匹配除换行符之外的任何单个字符。**((?!(insert|delete|update)).)+**:结合上面的部分,这个表达式会匹配一个或多个字符,但确保这些字符组成的字符串不是insert、delete或update。这个整体部分被捕获为一个组。**$**:匹配字符串的结束。综合上述分析,这个正则表达式将匹配以零个或多个空白字符开始,后跟一个或多个空白字符和SELECT(或大小写变体)关键词,再后跟一个或多个不是INSERT、DELETE或UPDATE(或大小写变体)的字符,并以字符串结束的字符串。例如,以下字符串将被匹配: SELECT column1 FROM table1但以下字符串将不会被匹配: UPDATE table1 SET column1 = 'value' SELECT INSERT column1 FROM table1注意:虽然这个正则表达式可以确保SELECT语句不包含INSERT、DELETE或UPDATE,但它不能确保整个SQL语句是有效的或安全的。对于复杂的SQL注入防护,建议使用更强大的工具或库。
-
密码强度正则表达式比如必须包含大写字母,小写字母和数字,至少8个字符等 需要一个密码强度正则表达式在用户注册时校验用户密码强度:密码至少8个字符,包括1个大写字母,1个小写字母和1个数字或特殊字符,例如#,?,!。网上搜索了一些解决方案分享给大家。 方案一 至少8-16个字符,至少1个大写字母,1个小写字母和1个数字,其他可以是任意字符: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/ 或者: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\s\S]{8,16}$/ 其中 [\s\S] 中的\s空白符,\S非空白符,所以[\s\S]是任意字符。也可以用 [\d\D]、[\w\W]来表示。 至少8个字符,至少1个大写字母,1个小写字母和1个数字,不能包含特殊字符(非数字字母): ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$ 至少8个字符,至少1个字母,1个数字和1个特殊字符: ^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$ 至少8个字符,至少1个大写字母,1个小写字母和1个数字: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$ 至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,} 最少8个最多十个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,10} 方案二 还有,你可以使用这个正则表达式: ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$ 这个正则表达式将强制执行这些规则: 至少1个大写字母English letter,(?=.*?[A-Z]) 至少1个小写英文字母,(?=.*?[a-z]) 至少1位数字,(?=.*?[0-9]) 至少有1个特殊字符,(?=.*?[#?!@$%^&*-]) 最小8个长度.{8,} 方案三 正则表达式没有AND运算符,所以编写正则表达式与有效密码匹配是非常困难的,当有效性被某些东西和其他东西等定义时… 但是,正则表达式确实有1个OR运算符,所以只需应用DeMorgan的定理,并编写1个与无效密码相匹配的正则表达式: 任何少于8个字符或任何没有数字或任何没有大写字母或任何没有小写字母或任何没有特殊字符的任何东西。 所以:^(.{0,7}|[^0-9]*|[^A-Z]*|[^a-z]*|[a-zA-Z0-9]*)$,如果有什么匹配的话,这是1个无效的密码。 方案四 由于特殊字符仅限于键盘中的特殊字符,因此可用于任何特殊字符: ^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$ 这个正则表达式将强制执行这些规则: – 至少1个大写英文字母 – 至少1个小写英文字母 – 至少1位数字 – 至少1个特殊字符 – 最少8个长度 方案五 根据我的情况,我遇到了最受欢迎的答案。例如,我的验证失败,其中包含;或[等字符。我对 white-listing 我的特殊字符不感兴趣,所以我用[^\w\s]作为测试 – 简单地把非字符(包括数字)和非空格字符放在一起。总而言之,这是对我有用的 至少8字符 至少1数字字符 至少1小写字母 至少1大写字母 至少1特殊字符 /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\w\s]).{8,}$/ 简单演示涵盖各种情况 方案六 导入JavaScript文件jquery.validate.min.js。 您可以使用此方法: JavaScript 代码: $.validator.addMethod("pwcheck", function (value) { return /[\@\#\$\%\^\&\*\(\)\_\+\!]/.test(value) && /[a-z]/.test(value) && /[0-9]/.test(value) && /[A-Z]/.test(value) }); 至少1个大写英文字母 至少1个小写英文字母 至少1位数字 至少1个特殊字符 方案七 尝试这个: – 最少6个字符 – 至少有1个大写字符 – 至少1个小写字符 – 至少1个特殊字符 表达式: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.]{6, 20}/ 可选特殊字符: 至少1个特殊字符 至少1个数字 特殊字符是可选的 最少6个字符,最多16个字符 表达式: /^(?=.*\d)(?=.*[a-zA-Z]).{6,20}$/ 如果不需要最小和最大条件,则删除.{6, 16} – 6是最小字符数限制 – 20是最大字符限制 – ?=表示匹配表达式 原文链接:https://www.cnblogs.com/loong-hon/p/11288028.html
-
Oracle 中like常用但是其效率不是高。特别是使用%a%-----》全局扫描,没有利用到任何索引。情况可以的条件尽量下使用a%------》可以利用正序的索引。%a------》可以利用反序的索引(当然得已有反序的索引)。使用instr函数取代like查询,可提高效率,在海量数据中效果尤其明显。1.%a%方式:select * from pub_yh_bm twhere instr(t.chr_bmdm,'2')>0等份于:select * from pub_yh_bm twhere t.chr_bmdm like '%2%'2.%a方式:select * from pub_yh_bm twhere instr(t.chr_bmdm,'110101')=length(t.chr_bmdm)-length('110101')+1等份于:select * from pub_yh_bm twhere t.chr_bmdm like '%110101'3.a%方式:select * from pub_yh_bm twhere instr(t.chr_bmdm,'11010101')=1等份于:select * from pub_yh_bm twhere t.chr_bmdm like '11010101%'ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与INSTR的功能相似3,REGEXP_SUBSTR :与SUBSTR的功能相似4,REGEXP_REPLACE :与REPLACE的功能相似它们在用法上与Oracle SQL 函数LIKE、INSTR、SUBSTR 和REPLACE 用法相同,但是它们使用POSIX 正则表达式代替了老的百分号(%)和通配符(_)字符。POSIX 正则表达式由标准的元字符(metacharacters)所构成:'^' 匹配输入字符串的开始位置,在方括号表达式中使用,此时它表示不接受该字符集合。'$' 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。'.' 匹配除换行符之外的任何单字符。'?' 匹配前面的子表达式零次或一次。'+' 匹配前面的子表达式一次或多次。'*' 匹配前面的子表达式零次或多次。'|' 指明两项之间的一个选择。例子'^([a-z]+|[0-9]+)$'表示所有小写字母或数字组合成的字符串。'( )' 标记一个子表达式的开始和结束位置。'[]' 标记一个中括号表达式。'{m,n}' 一个精确地出现次数范围,m=出现m次。\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。字符簇:[[:alpha:]] 任何字母。[[:digit:]] 任何数字。[[:alnum:]] 任何字母和数字。[[:space:]] 任何白字符。[[:upper:]] 任何大写字母。[[:lower:]] 任何小写字母。[[:punct:]] 任何标点符号。[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]。各种操作符的运算优先级\转义符(), (?:), (?=), [] 圆括号和方括号*, +, ?, {n}, {n,}, {n,m} 限定符^, $, anymetacharacter 位置和顺序范例:--regexp_like--查询value中以1开头60结束的记录并且长度是7位select * from fzq where value like '1____60';select * from fzq where regexp_like(value,'1....60');--查询value中以1开头60结束的记录并且长度是7位并且全部是数字的记录。--使用like就不是很好实现了。select * from fzq where regexp_like(value,'1[0-9]{4}60');-- 也可以这样实现,使用字符集。select * from fzq where regexp_like(value,'1[[:digit:]]{4}60');-- 查询value中不是纯数字的记录select * from fzq where not regexp_like(value,'^[[:digit:]]+$');-- 查询value中不包含任何数字的记录。select * from fzq where regexp_like(value,'^[^[:digit:]]+$');--查询以12或者1b开头的记录.不区分大小写。select * from fzq where regexp_like(value,'^1[2b]','i');--查询以12或者1b开头的记录.区分大小写。select * from fzq where regexp_like(value,'^1[2B]');-- 查询数据中包含空白的记录。select * from fzq where regexp_like(value,'[[:space:]]');--查询所有包含小写字母或者数字的记录。select * from fzq where regexp_like(value,'^([a-z]+|[0-9]+)$');--查询任何包含标点符号的记录。select * from fzq where regexp_like(value,'[[:punct:]]');select * from Dba_Tables b where regexp_like(b.table_name,'^[[A-Z]]$') And b.owner='SSCP2'来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26015009/viewspace-730802/,如需转载,请注明出处,否则将追究法律责任。
-
正则表达式实现重叠匹配正则表达式与正则匹配正则表达式正则匹配正则表达式实现重叠匹配1234import regexstring = '100101010001'str_re = '101'print(regex.findall(str_re, string, overlapped=True))普通的re库匹配,只能匹配一个’101’。正则表达式与正则匹配正则表达式正则表达式可理解为对数据筛选的表达式,是有限个原子和元字符组成。原子:基本组成单位,每个表达式至少有一个原子普通字符组成原子 非打印字符组成原子(不打印在输出台的字符)\n:换行\t:tab退格符通用字符组成原子\w:匹配任意字母、数字、下划线\W:与\w相反\d:匹配任意十进制数\D:与\d相反\s:匹配任意空白字符,如空格、换行、缩进\S:与\s相反原子表组成原子一组原子组成一个表,由[]声明表内原子优先级相等,但内容只出现依次若原子表以 ^ 开头,则表示取反12345678910111213141516#普通字符组成原子pat1 = "abcd" #非打印字符组成原子pat2 = "\n" #通用字符做原子pat3 = "\w" #原子表组成原子pat4 = "py[abc]"#可以匹配pya,pyb,pyc,但匹配pyab等原子表重复出现的情况失败 #原子表开头带 ^ 表示取反pat5 = "py[^abc]"#第三个位置匹配除了a,b,c外的任意一个字符元字符:正则表达式中具有特殊含义的字符.匹配任意字符,除了换行符^匹配字符串开始的位置$匹配字符串结束的位置,当出现多组符合的匹配时,返回字符串最后的那组匹配*匹配 0,1,n 次前面的原子【贪婪模式:尽可能多的匹配】?匹配 0,1 次前面的原子【懒惰模式:精确匹配】+匹配 1,n 次前面的原子{ j }前面的原子出现 j 次{ j , }前面的原子至少出现 j 次{ j , k }前面的原子至少出现 j 次,至多出现 k 次i | j匹配 i 或 j ,若 i 与 j 同时出现,匹配 i( )组,限制这组数据的组合如()内所描述一样,只返回符合括号内描述的内容模式修正符即函数中 flag 位置的参数,在不改变正则表达式的情况下改变其含义,调整匹配结果。re.I匹配时忽略大小写re.M多行匹配re.L本地化识别匹配re.U根据unicon字符匹配,影响\w \Wre.S匹配包括换行符正则匹配正则表达式是对字符串进行模糊匹配,其中一个应用为正则匹配。正则匹配是python爬虫的一个使用技术,用于在爬取的文本信息中提取目标信息。正则匹配常用的函数:(调用正则表达式模块re)re.search(pat, str[, flag]):扫描字符串str,返回pat的位置(第一次成功匹配的),flag用于控制正则表达式的匹配方式1234import restr = 'python'pat = 'pytho[a-n]'print(re.search(pat, str))re.match(pat, str[, flag]):扫描字符串str开始的位置,返回pat的位置(第一次成功匹配的),flag用于控制正则表达式的匹配方式【若开始就不符合则结束,返回none】123456import restr_1 = 'hello world'str_2 = 'world hello'pat = 'world'print(re.match(pat, str_1))print(re.match(pat, str_2))re.complie(pat[, flag]):编译正则表达式pat,返回正则表达式对象findall(str[, pos[, endpos]]):匹配所有,用列表返回string中所有匹配到的子串【不止第一次】,pos和endpos可指定在string中的起始位置re.complie(pat).findall(str):全局匹配函数,匹配str中所有符合pat的子串,装入一个列表返回结果12345import restr = "hello world hello world hello world"pat = "hello"print(re.complie(pat).findall(str))print(re.complie(pat).findall(str, 5, 15))re.sub(pat, repl, str[, count[, flag]]):替换字符串中的匹配项【清洗数据】,可用count指定最大替换次数12345import restr = "400-823-823"pat = "-"#短横改空格,最大替换次数2str_new = re.sub(pat, " ", str, count=2)
-
本文主要讲两个常用场景: 场景1:文本中取出“金额数”; 场景2:登录某网站时,需要从手机接收的验证码信息中获取“验证码数字”。场景1原理: 一般文本中的金额数都有前缀或后缀,见下图,货币是后缀,符号是前缀。 (1)以“前缀”来匹配金额数的正则表达式可写成:(?<=¥|$|€|£|₣)\d+\.?\d* (2)以“后缀”来匹配金额数的正则表达式可写成:\d+\.?\d*(?=元|人民币|美元|欧元|英镑|法郎|日元) (3)前缀后缀都要考虑到,可用"|"或符号连接上面两个正则表达式:(?<=¥|$|€|£|₣)\d+\.?\d*|\d+\.?\d*(?=元|人民币|美元|欧元|英镑|法郎|日元)场景2原理: 一般手机验证码信息中的验证码数字之前定有“验证码”三个字。 例如:中国移动短信:“尊敬的客户,本次短信验证码为440562,您在畅由平台办理的中国移动12345678900手机号扣减移动1080积分兑换为畅由积分的业务,请于60秒内输入验证,请勿告知他人。中国移动不会以任何方式向你索取该验证码,如非本人操作,请核实确认。详询10086。【中国移动 积分商城】” (1)可根据“验证码”这三字来匹配验证码数字,正则表达式可写成:验证码.*?(\d+)注:Studio中主要用的控件如下:(1)查找文本中所有符合的金额数:“regex_findall-正则查找所有”控件;(2)查找文本中第一个符合的金额数:“regex_search-正则搜索”控件。Studio机器人脚本样例可见附件“正则匹配_金额or验证码.zip”。
-
函数名函数说明样例返回说明兼容对象语言位置ADD_MONTHS2(p1,p2) 当前日期 P1 增加 p2 个月的月末测试案例: select ADD_MONTHS2('2018-04-22',2); 输出: 20180630dateTDC语言https://bbs.huaweicloud.com/forum/thread-173862-1-1.htmlADD_MONTHS3(p1,p2)当前日期 P1 增加 p2 个月的月末测试案例: select ADD_MONTHS3(CAST('20180502' AS DATE FORMAT 'YYYYMMDD'),3)输出: 20180831dateTDC语言 DPT_MOB12(p1,p2)计算变量VAR514测试案例:select DPT_MOB12('1010101',30);输出: 1intergerTDC语言 edit_distance_similarity(p1,p2)比较两个字符串的相似度测试案例:select edit_distance_similarity('河北沧州东朔股份有限公司','河北沧州东朔股份有限公司')输出: 100select edit_distance_similarity('河北沧州东朔股份有限公司','沧州东朔房地产开发又发公司')输出: 50intergerORACLEC语言 max_col(p1,p2)计算浮点数最大值测试案例:select max_col(3.3,2.2);输出: 3.30floatTDC语言 min_col(p1,p2)计算浮点数最小值测试案例:select min_col(3.3,2.2);输出: 2.20floatTDC语言 month_between(p1,p2)间隔月份测试案例:select month_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: 7intergerTDC语言 month_between1(p1,p2) P1(YYYYMM)-P2(YYYYMM)的月份数测试案例:select month1_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: -8intergerTDC语言 month_between1(p1,p2) P1(YYYYMM)-P2(YYYYMM)的月份数测试案例:select month_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: 7intergeroracleC语言 specialdata(inputdata varchar,inputtype varchar)根据获取的时间类型,获取对应的时间本月初:specialdate('20190806',11),返回时间:20190801本月末:specialdate('20190806',12),返回时间:20190831上月初:specialdate('20190806',13),返回时间:20190701上月末:specialdate('20190806',14),返回时间:201907031本季初:specialdate('20190806',21),返回时间:20190701本季末:specialdate('20190806',22),返回时间:20190930上季初:specialdate('20190806',23),返回时间:20190301上季末:specialdate('20190806',44),返回时间:20190630本年初:specialdate('20190806',31),返回时间:20190101本年末:specialdate('20190806',32),返回时间:201901231上年初:specialdate('20190806',33),返回时间:20180101上年末:specialdate('20190806',34);返回时间:201801230dateTDplsql substring_index(str,delim,count)按关键字截取字符串 例:select substring_index('blog.jb51.net','.', 2) as abstract from my_content_t结果:blog.jb51 textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173882-1-1.htmlchar2hexint(text)GBK字符集下的字符的16进制select char2hexint('1中2文'); char2hexint -------------- 31D6D032CEC4textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173886-1-1.htmlchars(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select chars('1中2文'); chars------- 6integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173892-1-1.htmldaynumber_of_calendar(date)输入日期与'1900-01-01'相差的天数select daynumber_of_calendar(current_date); daynumber_of_calendar----------------------- 44508integerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173897daynumber_of_month(date)一个月的第几天select daynumber_of_month(date '2021-11-09'); daynumber_of_month-------------------- 9integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173900-1-1.htmldaynumber_of_week(date)一个周的第几天,在td中,周日为1,周六为7select daynumber_of_week(date '2021-11-07'); daynumber_of_week------------------- 1integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173909-1-1.htmldaynumber_of_year(date)一个年的第几天select daynumber_of_year(date '2021-11-06'); daynumber_of_year------------------- 310integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173911-1-1.htmllpad(character varying,integer,character varying)左边填充,td中1个中文占2个字符,导致td与dws结果不一样select public.lpad('1中2文',10,'#'); lpad ------------ ####1中2文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-174007-1-1.htmlmonthnumber_of_year(date)一个年的第几月select monthnumber_of_year(date '2021-11-10'); monthnumber_of_year--------------------- 11integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173927-1-1.htmlmonths_between(date,date)日期相差月份数量select months_between(date '2021-11-10',date '2021-09-20'); months_between---------------- 1.6774numericTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173935&page=1&authorid=&replytype=&extra=#pid1396442months_between_double(date,date)日期相差月份数量(中间函数),一般不使用,因此c函数只能返回double类型,但一般函数返回integer。 double precisionTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173936numtoyminterval(integer,character varying)数字转interval,与td保持一致,第二个参数输入只能是YEAR或者MONTHselect numtoyminterval(100, 'MONTH'); numtoyminterval----------------- 8 years 4 monsintervalTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173872-1-1.htmloadd_months(date,integer)获取多个月以后(以前)的同样的日期。若是月末取月末(区别与add_months)select oadd_months(date '2020-02-29',-1); oadd_months------------- 2020-01-31select oadd_months(date '2020-02-28',1); oadd_months------------- 2020-03-28dateTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173876quarternumber_of_year(date)一个年的第几个季度select quarternumber_of_year(date '2021-10-01'); quarternumber_of_year----------------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173879-1-1.htmlregexp_instr(text,text,integer)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:匹配的其实位置通过正则表达式搜索字符位置,需考虑中文字符select regexp_instr('中1文2','\d',1); regexp_instr-------------- 3intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173885-1-1.htmlregexp_similar(text,text,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写函数功能:判断输入的字符串是否满足输入的正则表达式select regexp_similar('12345678902','\d+','c'); regexp_similar---------------- 1(1 row)cmbgdw=> select regexp_similar('1234567890w','\d+','c'); regexp_similar---------------- 0select regexp_similar('1234567890W','\d+[a-z]','c'); regexp_similar---------------- 0(1 row)cmbgdw=> select regexp_similar('1234567890W','\d+[a-z]','i'); regexp_similar---------------- 1intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173888-1-1.htmlregexp_substr(text,text,integer,integer,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:搜索起始位置第四个参数:取匹配到的第几个组字符第五个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写,默认为c函数功能:通过正则表达式截取字符cmbgdw=> select regexp_substr('1中2文','\d',1,1,'i'); regexp_substr--------------- 1(1 row)cmbgdw=> select regexp_substr('1中2文','\d',1,2,'i'); regexp_substr--------------- 2(1 row)textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173890-1-1.htmlregexp_substr(text,text,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:是否区分大小写等作用同上面的regexp_substr(text,text,1,1,text)select regexp_substr('1中2文','\d','i'); regexp_substr--------------- 1textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173895-1-1.htmlround2(numeric,integer)td无该函数,用于适配td的奇进偶舍的进制,作用:对于小数需要进行round操作时,0.5这样的需要判断进位的前一位数字,若是奇数,则进一位,若是偶数,则舍弃 select round2(1.25,1); round2-------- 1.2(1 row)cmbgdw=> select round2(1.35,1); round2-------- 1.4numericTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173896-1-1.htmlstrtok(text,text,integer)适配td的strtok函数,作用是按指定分隔符切割字符串。第一个参数:输入的字符第二个参数:分隔符第三个参数:取第几位select strtok('a,b,c,d',',',3); strtok-------- ctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173899-1-1.htmltd_char(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_char('1中2文'); td_char--------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173902-1-1.htmltd_char_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_char_length('1中2文'); td_char_length---------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173904-1-1.htmltd_character(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_character('1中2文'); td_character-------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173983td_character_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_character_length('1中2文'); td_character_length--------------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173984td_day_of_calendar(date)输入日期与'1900-01-01'相差的天数select td_day_of_calendar(date '2021-11-10'); td_day_of_calendar-------------------- 44509intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173986td_day_of_month(date)一个月的第几天select td_day_of_month(date '2021-11-10'); td_day_of_month----------------- 10intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173987td_day_of_month(timestamp without time zone)一个月的第几天select td_day_of_month( '2021-11-10 10:01:01'); td_day_of_month----------------- 10intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173989td_day_of_week(date)一个周的第几天,在td中,周日为1,周六为7select td_day_of_week(date '2021-11-10'); td_day_of_week---------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173993td_day_of_week(timestamp without time zone)一个周的第几天,在td中,周日为1,周六为7select td_day_of_week( '2021-11-10 10:01:01'); td_day_of_week---------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173994td_day_of_year(date)一个年的第几天select td_day_of_year(date '2021-11-10'); td_day_of_year---------------- 314intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173996td_day_of_year(timestamp without time zone)一个年的第几天select td_day_of_year( '2021-11-10 10:10:10'); td_day_of_year---------------- 314intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173997td_instr(text,text,integer)返回某个字符的位置,第三个参数是指定搜索位置,类似instr,考虑td与dws字符集影响而新增select td_instr('1中2文','2',1); td_instr---------- 4(1 row)select instr('1中2文','2',1); instr------- 3(1 row)textTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174000td_left(text,integer)与left类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select td_left('1中2文',3); td_left--------- 1中select td_left('1中2文',2); td_left--------- 1\x0Fselect left('1中2文',2); left------ 1中textTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174003td_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_length('1中2文'); td_length----------- 6(1 row)cmbgdw=> select length('1中2文'); length-------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174009td_month_begin(date)获取当天月初日期select td_month_begin(date '2021-11-10'); td_month_begin---------------- 2021-11-01dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173937-1-1.htmltd_month_begin(timestamp without time zone) dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173939-1-1.htmltd_month_end(date)获取当天月末日期select td_month_end(date '2021-11-10'); td_month_end-------------- 2021-11-30dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173941-1-1.htmltd_month_end(timestamp without time zone) dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173942-1-1.htmltd_quarter_of_year(date)一个年的第几个季度select td_quarter_of_year(date '2021-10-01') ; td_quarter_of_year-------------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173943-1-1.htmltd_regexp_replace(text,text,text)因dws也有regexp_replace,此函数区别区别于dws,因此命名为td_regexp_replace第一个参数:输入的字符串第二个参数:输入的正则表达式第三个参数:匹配后替换的字符select td_regexp_replace('1a2b3c','\d','w'); td_regexp_replace------------------- wawbwctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173944-1-1.htmltd_regexp_replace(text,text,text,integer,integer,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:匹配到替换的字符第四个参数:搜索起始位置第五个参数:取匹配到的第几个组字符,输入0,则对所有匹配的都做替换,只接受0和1第六个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写,默认为c函数功能:通过正则表达式替换字符select td_regexp_replace('1a2b3c','\d','w',2,1,'i'); td_regexp_replace------------------- 1awb3c(1 row)cmbgdw=> select td_regexp_replace('1a2b3c','\d','w',2,0,'i'); td_regexp_replace------------------- 1awbwctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173945-1-1.htmltd_right(text,integer)与right类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select right('1中2文',2); right------- 2文(1 row)cmbgdw=> select td_right('1中2文',2); td_right---------- 文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173946-1-1.htmltd_substr(text,integer)与substr类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select td_substr('1中2文',4); td_substr----------- 2文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173954-1-1.htmltd_substr(text,integer,integer)select td_substr('1中2文',1,3); td_substr----------- 1中textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173959-1-1.htmltrunc(date,character varying)获取某些类型的日期select trunc(date '2021-11-10','iw'); trunc ------------ 2021-11-08dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173875-1-1.htmlweeknumber_of_calendar(date)输入日期与'1900-01-01'相差的周数select weeknumber_of_calendar(date '2021-11-10'); weeknumber_of_calendar------------------------ 6358intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173877-1-1.htmlweeknumber_of_year(date)当年的周数,考虑td的一周开始是周日select weeknumber_of_year(date '2021-11-10'); weeknumber_of_year-------------------- 45intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173883-1-1.htmlyearnumber_of_year(date)当年的年数select yearnumber_of_year(date '2021-11-10'); yearnumber_of_year-------------------- 2021intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173887-1-1.htmlzeroifnull(anyelement)如果输入是null值,则返回0select zeroifnull(null); zeroifnull------------ 0cmbgdw=> create temp table mytbl(col int);cmbgdw=> drop table mytbl;DROP TABLEcmbgdw=> create temp table mytbl(col int);NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'col' as the distribution column by default.HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.CREATE TABLEcmbgdw=> insert into mytbl select null;INSERT 0 1cmbgdw=> select zeroifnull(col) from mytbl; zeroifnull------------ 0analyelementTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173891-1-1.htmlzeroifnull(unknown) intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173891-1-1.html
-
函数名函数说明样例返回说明兼容对象语言位置ADD_MONTHS2(p1,p2) 当前日期 P1 增加 p2 个月的月末测试案例: select ADD_MONTHS2('2018-04-22',2); 输出: 20180630dateTDC语言https://bbs.huaweicloud.com/forum/thread-173862-1-1.htmlADD_MONTHS3(p1,p2)当前日期 P1 增加 p2 个月的月末测试案例: select ADD_MONTHS3(CAST('20180502' AS DATE FORMAT 'YYYYMMDD'),3)输出: 20180831dateTDC语言 DPT_MOB12(p1,p2)计算变量VAR514测试案例:select DPT_MOB12('1010101',30);输出: 1intergerTDC语言 edit_distance_similarity(p1,p2)比较两个字符串的相似度测试案例:select edit_distance_similarity('河北沧州东朔股份有限公司','河北沧州东朔股份有限公司')输出: 100select edit_distance_similarity('河北沧州东朔股份有限公司','沧州东朔房地产开发又发公司')输出: 50intergerORACLEC语言 max_col(p1,p2)计算浮点数最大值测试案例:select max_col(3.3,2.2);输出: 3.30floatTDC语言 min_col(p1,p2)计算浮点数最小值测试案例:select min_col(3.3,2.2);输出: 2.20floatTDC语言 month_between(p1,p2)间隔月份测试案例:select month_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: 7intergerTDC语言 month_between1(p1,p2) P1(YYYYMM)-P2(YYYYMM)的月份数测试案例:select month1_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: -8intergerTDC语言 month_between1(p1,p2) P1(YYYYMM)-P2(YYYYMM)的月份数测试案例:select month_between(CAST('20180422' AS DATE FORMAT 'YYYYMMDD'),CAST('20181202' AS DATE FORMAT 'YYYYMMDD'))输出: 7intergeroracleC语言 specialdata(inputdata varchar,inputtype varchar)根据获取的时间类型,获取对应的时间本月初:specialdate('20190806',11),返回时间:20190801本月末:specialdate('20190806',12),返回时间:20190831上月初:specialdate('20190806',13),返回时间:20190701上月末:specialdate('20190806',14),返回时间:201907031本季初:specialdate('20190806',21),返回时间:20190701本季末:specialdate('20190806',22),返回时间:20190930上季初:specialdate('20190806',23),返回时间:20190301上季末:specialdate('20190806',44),返回时间:20190630本年初:specialdate('20190806',31),返回时间:20190101本年末:specialdate('20190806',32),返回时间:201901231上年初:specialdate('20190806',33),返回时间:20180101上年末:specialdate('20190806',34);返回时间:201801230dateTDplsql substring_index(str,delim,count)按关键字截取字符串 例:select substring_index('blog.jb51.net','.', 2) as abstract from my_content_t结果:blog.jb51 textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173882-1-1.htmlchar2hexint(text)GBK字符集下的字符的16进制select char2hexint('1中2文'); char2hexint -------------- 31D6D032CEC4textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173886-1-1.htmlchars(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select chars('1中2文'); chars------- 6integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173892-1-1.htmldaynumber_of_calendar(date)输入日期与'1900-01-01'相差的天数select daynumber_of_calendar(current_date); daynumber_of_calendar----------------------- 44508integerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173897daynumber_of_month(date)一个月的第几天select daynumber_of_month(date '2021-11-09'); daynumber_of_month-------------------- 9integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173900-1-1.htmldaynumber_of_week(date)一个周的第几天,在td中,周日为1,周六为7select daynumber_of_week(date '2021-11-07'); daynumber_of_week------------------- 1integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173909-1-1.htmldaynumber_of_year(date)一个年的第几天select daynumber_of_year(date '2021-11-06'); daynumber_of_year------------------- 310integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173911-1-1.htmllpad(character varying,integer,character varying)左边填充,td中1个中文占2个字符,导致td与dws结果不一样select public.lpad('1中2文',10,'#'); lpad ------------ ####1中2文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-174007-1-1.htmlmonthnumber_of_year(date)一个年的第几月select monthnumber_of_year(date '2021-11-10'); monthnumber_of_year--------------------- 11integerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173927-1-1.htmlmonths_between(date,date)日期相差月份数量select months_between(date '2021-11-10',date '2021-09-20'); months_between---------------- 1.6774numericTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173935&page=1&authorid=&replytype=&extra=#pid1396442months_between_double(date,date)日期相差月份数量(中间函数),一般不使用,因此c函数只能返回double类型,但一般函数返回integer。 double precisionTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173936numtoyminterval(integer,character varying)数字转interval,与td保持一致,第二个参数输入只能是YEAR或者MONTHselect numtoyminterval(100, 'MONTH'); numtoyminterval----------------- 8 years 4 monsintervalTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173872-1-1.htmloadd_months(date,integer)获取多个月以后(以前)的同样的日期。若是月末取月末(区别与add_months)select oadd_months(date '2020-02-29',-1); oadd_months------------- 2020-01-31select oadd_months(date '2020-02-28',1); oadd_months------------- 2020-03-28dateTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173876quarternumber_of_year(date)一个年的第几个季度select quarternumber_of_year(date '2021-10-01'); quarternumber_of_year----------------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173879-1-1.htmlregexp_instr(text,text,integer)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:匹配的其实位置通过正则表达式搜索字符位置,需考虑中文字符select regexp_instr('中1文2','\d',1); regexp_instr-------------- 3intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173885-1-1.htmlregexp_similar(text,text,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写函数功能:判断输入的字符串是否满足输入的正则表达式select regexp_similar('12345678902','\d+','c'); regexp_similar---------------- 1(1 row)cmbgdw=> select regexp_similar('1234567890w','\d+','c'); regexp_similar---------------- 0select regexp_similar('1234567890W','\d+[a-z]','c'); regexp_similar---------------- 0(1 row)cmbgdw=> select regexp_similar('1234567890W','\d+[a-z]','i'); regexp_similar---------------- 1intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173888-1-1.htmlregexp_substr(text,text,integer,integer,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:搜索起始位置第四个参数:取匹配到的第几个组字符第五个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写,默认为c函数功能:通过正则表达式截取字符cmbgdw=> select regexp_substr('1中2文','\d',1,1,'i'); regexp_substr--------------- 1(1 row)cmbgdw=> select regexp_substr('1中2文','\d',1,2,'i'); regexp_substr--------------- 2(1 row)textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173890-1-1.htmlregexp_substr(text,text,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:是否区分大小写等作用同上面的regexp_substr(text,text,1,1,text)select regexp_substr('1中2文','\d','i'); regexp_substr--------------- 1textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173895-1-1.htmlround2(numeric,integer)td无该函数,用于适配td的奇进偶舍的进制,作用:对于小数需要进行round操作时,0.5这样的需要判断进位的前一位数字,若是奇数,则进一位,若是偶数,则舍弃 select round2(1.25,1); round2-------- 1.2(1 row)cmbgdw=> select round2(1.35,1); round2-------- 1.4numericTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173896-1-1.htmlstrtok(text,text,integer)适配td的strtok函数,作用是按指定分隔符切割字符串。第一个参数:输入的字符第二个参数:分隔符第三个参数:取第几位select strtok('a,b,c,d',',',3); strtok-------- ctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173899-1-1.htmltd_char(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_char('1中2文'); td_char--------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173902-1-1.htmltd_char_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_char_length('1中2文'); td_char_length---------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173904-1-1.htmltd_character(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_character('1中2文'); td_character-------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173983td_character_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_character_length('1中2文'); td_character_length--------------------- 6intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173984td_day_of_calendar(date)输入日期与'1900-01-01'相差的天数select td_day_of_calendar(date '2021-11-10'); td_day_of_calendar-------------------- 44509intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173986td_day_of_month(date)一个月的第几天select td_day_of_month(date '2021-11-10'); td_day_of_month----------------- 10intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173987td_day_of_month(timestamp without time zone)一个月的第几天select td_day_of_month( '2021-11-10 10:01:01'); td_day_of_month----------------- 10intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173989td_day_of_week(date)一个周的第几天,在td中,周日为1,周六为7select td_day_of_week(date '2021-11-10'); td_day_of_week---------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173993td_day_of_week(timestamp without time zone)一个周的第几天,在td中,周日为1,周六为7select td_day_of_week( '2021-11-10 10:01:01'); td_day_of_week---------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173994td_day_of_year(date)一个年的第几天select td_day_of_year(date '2021-11-10'); td_day_of_year---------------- 314intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173996td_day_of_year(timestamp without time zone)一个年的第几天select td_day_of_year( '2021-11-10 10:10:10'); td_day_of_year---------------- 314intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=173997td_instr(text,text,integer)返回某个字符的位置,第三个参数是指定搜索位置,类似instr,考虑td与dws字符集影响而新增select td_instr('1中2文','2',1); td_instr---------- 4(1 row)select instr('1中2文','2',1); instr------- 3(1 row)textTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174000td_left(text,integer)与left类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select td_left('1中2文',3); td_left--------- 1中select td_left('1中2文',2); td_left--------- 1\x0Fselect left('1中2文',2); left------ 1中textTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174003td_length(text)返回GBK下的字符的字节长度,与UTF8的长度有差异select td_length('1中2文'); td_length----------- 6(1 row)cmbgdw=> select length('1中2文'); length-------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=174009td_month_begin(date)获取当天月初日期select td_month_begin(date '2021-11-10'); td_month_begin---------------- 2021-11-01dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173937-1-1.htmltd_month_begin(timestamp without time zone) dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173939-1-1.htmltd_month_end(date)获取当天月末日期select td_month_end(date '2021-11-10'); td_month_end-------------- 2021-11-30dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173941-1-1.htmltd_month_end(timestamp without time zone) dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173942-1-1.htmltd_quarter_of_year(date)一个年的第几个季度select td_quarter_of_year(date '2021-10-01') ; td_quarter_of_year-------------------- 4intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173943-1-1.htmltd_regexp_replace(text,text,text)因dws也有regexp_replace,此函数区别区别于dws,因此命名为td_regexp_replace第一个参数:输入的字符串第二个参数:输入的正则表达式第三个参数:匹配后替换的字符select td_regexp_replace('1a2b3c','\d','w'); td_regexp_replace------------------- wawbwctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173944-1-1.htmltd_regexp_replace(text,text,text,integer,integer,text)第一个参数:输入的字符串第二个参数:正则表达式第三个参数:匹配到替换的字符第四个参数:搜索起始位置第五个参数:取匹配到的第几个组字符,输入0,则对所有匹配的都做替换,只接受0和1第六个参数:是否区分大小写等,输入i为不区分大小写,c为区分大小写,默认为c函数功能:通过正则表达式替换字符select td_regexp_replace('1a2b3c','\d','w',2,1,'i'); td_regexp_replace------------------- 1awb3c(1 row)cmbgdw=> select td_regexp_replace('1a2b3c','\d','w',2,0,'i'); td_regexp_replace------------------- 1awbwctextTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173945-1-1.htmltd_right(text,integer)与right类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select right('1中2文',2); right------- 2文(1 row)cmbgdw=> select td_right('1中2文',2); td_right---------- 文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173946-1-1.htmltd_substr(text,integer)与substr类似,考虑td与dws字符集影响而新增,若中间截取了中文,返回固定的\x0F字符select td_substr('1中2文',4); td_substr----------- 2文textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173954-1-1.htmltd_substr(text,integer,integer)select td_substr('1中2文',1,3); td_substr----------- 1中textTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173959-1-1.htmltrunc(date,character varying)获取某些类型的日期select trunc(date '2021-11-10','iw'); trunc ------------ 2021-11-08dateTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173875-1-1.htmlweeknumber_of_calendar(date)输入日期与'1900-01-01'相差的周数select weeknumber_of_calendar(date '2021-11-10'); weeknumber_of_calendar------------------------ 6358intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173877-1-1.htmlweeknumber_of_year(date)当年的周数,考虑td的一周开始是周日select weeknumber_of_year(date '2021-11-10'); weeknumber_of_year-------------------- 45intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173883-1-1.htmlyearnumber_of_year(date)当年的年数select yearnumber_of_year(date '2021-11-10'); yearnumber_of_year-------------------- 2021intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173887-1-1.htmlzeroifnull(anyelement)如果输入是null值,则返回0select zeroifnull(null); zeroifnull------------ 0cmbgdw=> create temp table mytbl(col int);cmbgdw=> drop table mytbl;DROP TABLEcmbgdw=> create temp table mytbl(col int);NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'col' as the distribution column by default.HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.CREATE TABLEcmbgdw=> insert into mytbl select null;INSERT 0 1cmbgdw=> select zeroifnull(col) from mytbl; zeroifnull------------ 0analyelementTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173891-1-1.htmlzeroifnull(unknown) intergerTDplsqlhttps://bbs.huaweicloud.com/forum/thread-173891-1-1.html
上滑加载中
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签