• 售前

  • 售后

热门帖子
入门百科

PostgreSQL 正则表达式更换-使用变量方式

[复制链接]
东未红 显示全部楼层 发表于 2021-10-26 13:32:48 |阅读模式 打印 上一主题 下一主题
###不定期更新
把AAAA替换为A-A-A-A-
javascript
  1. alert('AAAA'.replace(/([A]{1})/g,"$1-"));
复制代码
()中的内容用变量$1 $2 $n代替
PostgreSQL
  1. select regexp_replace('AAAAAAAAAAAAAAAAAAAAAA','([A-Z]{1})','\1-','g')
复制代码
()中的内容用变量\1 \2 \n代替
获取大括号中的内容
  1. select f1[1] from regexp_matches('asdfadfadsf{_id}','[\{]{1}(.*?)[\}]{1}') as f1
复制代码
字符串去重
  1. -- \1表示只匹配第一个子串
  2. select regexp_replace('adsfjjbkk中中','(.)(\1)+','\1','g')
  3. select regexp_replace('adaaasfjjjbkk','(.).*(\1)+','\1','g')
复制代码
去除字符串末了两位
  1. select substring('abc123d4' from '^(.*?)..$');
  2. -output abc123
复制代码
擦除全部空格
  1. select * from regexp_matches(' abc123d 4测试 ','[^ ]+','g');
  2. select * from regexp_matches(' abc123d4测试 ','[^ ]+','g');
  3. -output abc123
复制代码
擦除左右两边的空格
  1. select regexp_replace(' abc123d4 测试 ','^[ ]?(.*?)[ ]?$','\1','g');
复制代码
从html中提取字符串
  1. select f1 from regexp_split_to_table('<div id="u1"><a href="http://news.baidu.com" rel="external nofollow" name="tj_trnews" class="mnav">新闻</a><a href="https://www.hao123.com" rel="external nofollow" name="tj_trhao123" class="mnav">hao123</a><a href="http://map.baidu.com" rel="external nofollow" name="tj_trmap" class="mnav">地图</a><a href="http://v.baidu.com" rel="external nofollow" name="tj_trvideo" class="mnav">视频</a><a href="http://tieba.baidu.com" rel="external nofollow" name="tj_trtieba" class="mnav">贴吧</a><a href="http://xueshu.baidu.com" rel="external nofollow" name="tj_trxueshu" class="mnav">学术</a><a href="https://passport.baidu.com/v2/?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2F&amp;sms=5" rel="external nofollow" name="tj_login" class="lb" onclick="return false;">登录</a><a href="http://www.baidu.com/gaoji/preferences.html" rel="external nofollow" name="tj_settingicon" class="pf">设置</a><a href="http://www.baidu.com/more/" rel="external nofollow" name="tj_briicon" class="bri" style="display: block;">更多产品</a></div>','<[^>]*>') as f1 where f1<>''
复制代码
取开头4个字符和末了4个字符
  1. with cte as(
  2. select '实际月份少一个月a1.' as f limit 1
  3. ) select (regexp_matches(f,'^(.{4})'))[1] as start,(regexp_matches(f,'(.{4})$'))[1] as end from cte
复制代码
****提取字段
  1. select array_agg(vals[1]),array_agg(vals[2]) from regexp_matches('字段1:值1,字段2:,:3,字段4:4','(\w+)?[:]{1}(\w+)?,?','g') as vals;
  2. select array_agg(vals[1]),array_agg(vals[2]) from regexp_matches('字段1=值1,字段2=,=3,字段4=4','(\w+)?[=]{1}(\w+)?,?','g') as vals;
复制代码
正向匹配和反向匹配
  1. --正向匹配,连继的3个字母右边不能出现:
  2. select * from regexp_matches('asf:::::','[a-zA-Z]{3}(?!:)') as f1
  3. --反向匹配,连继的3个字母左边不能出现:
  4. select * from regexp_matches(':::::asdf','(?<!:)[a-zA-Z]{3}') as f1
复制代码
查询name字段中不包罗数字的记录
  1. --仅整数
  2. select * from test where name !~'[0-9]+'
  3. --高大上的写法,包含带符号的整数和浮点数及科学计数
  4. select * from test where name !~'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?'
复制代码
匹配固定电话或传真
  1. select '(0871)68111111'~'^(\([0-9]{3,4}\)|[0-9]{3,4}-)?[0-9]{7,8}$'
  2. /*
  3. 接受以下格式
  4. (0871)7位或8位电话号码
  5. (871)7位或8位电话号码
  6. 0871-7位或8位电话号码
  7. 871-7位或8位电话号码
  8. */
复制代码
匹配移动电话
  1. select '+8613000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  2. '8613000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  3. '(+86)13000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  4. '(86)13000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  5. '(+86)13000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  6. '(86)13000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$',
  7. '13000000000'~'^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$'
  8. --提取移动电话
  9. select tmp[8] from regexp_matches('(+86)13000000000','^((\+86)|(86)|(\(\+86\))|(\(86\))|((\+86))|((86)))?(1[0-9]{10})$','g') as tmp
复制代码
限定用户名
用户名必须由6-16位的A-Z,a-z,0-9,_构成,而且不能为纯数字
  1. constraint ck_users_uname check(uname~'^[0-9a-zA-Z_]{6,16}$' and uname !~ '^[0-9]+$' ),
复制代码
要想给“麻将”和“速率”这两个词加粗
  1. --同时匹配两个字一次,不能用中括号[]
  2. select regexp_replace('打麻将出老千速度太快将速','((麻将)|(速度){1})','<strong>\1</strong>','g')
  3. --不正确的写法,请注意看它们之间的区别
  4. select regexp_replace('打麻将出老千速度太快将速','([麻将|速度]{2})','<strong>\1</strong>','g')
  5. select regexp_replace('打麻将出老千速度太快将速','([麻将|速度]{1})','<strong>\1</strong>','g')
复制代码
度分秒格式转换为度格式
度精确至小数点6位.只进行了一次浮点运算.
  1. with split as(
  2. select cast(deg[1] as integer) as du,
  3. cast(deg[2] as integer) as fen ,
  4. cast(deg[3] as integer) as miao,
  5. deg[4] as direction,
  6. 1000000 as f1
  7. from ( select regexp_matches('984759','([-+]?[0-9]{1,3})[°]?([0-9]{2})[′]?([0-9]{2})[″]?([SNEW]?)') as deg) as tmp
  8. ),cte as(
  9. select
  10. (case when du<0 or 'S'=direction or 'W'=direction then -1 else 1 end) as sign,
  11. abs(du) * f1 as du,
  12. fen * f1 as fen,
  13. miao * f1 as miao,
  14. cast(f1 as float8) as f1
  15. from split
  16. )select ((du + fen/60 + miao/3600) * sign) / f1 from cte;
复制代码
字符串由数字\大写字母\小写字母\下划线@符号构成,且必须包罗数字\大写字母\小写字母,数字\大写字母\小写字母必须至少出现一次,长度为6-14位
  1. select * from regexp_matches('Kmblack123456','^(?=.*[0-9]+)(?=.*[A-Z]+)(?=.*[a-z]+)[0-9a-zA-Z_@]{6,14}$') as f1
复制代码
字符串由数字\大写字母\小写字母\下划线@符号构成,而且不能以数字开头,且必须包罗数字\大写字母\小写字母,数字\大写字母\小写字母必须至少出现一次,长度为6-14位
  1. select * from regexp_matches('1Kmblack123456','^(?![0-9]+)(?=.*[0-9]+)(?=.*[A-Z]+)(?=.*[a-z]+)[0-9a-zA-Z_@]{6,14}$') as f1
  2. select * from regexp_matches('Kmblack123456','^(?![0-9]+)(?=.*[0-9]+)(?=.*[A-Z]+)(?=.*[a-z]+)[0-9a-zA-Z_@]{6,14}$') as f1
复制代码
日期时间提取
支持1900-2199年的时间,返回的数据索引的寄义:
1:完成日期和时间
2.仅日期部分
3.仅年部份
4.年代的头二位(19/20/21)
5.月部分
6.日期部份
7.完备时间部份
8.小时部分
9.分钟部分
10.秒部分
  1. select * from regexp_matches('2100-01-02T01:02:03Z','^((((19|20|21)[0-9]{2})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))T((?:(?:([01]?[0-9]|2[0-3]):)?([0-5]?[0-9]):)?([0-5]?[0-9]))Z)$') as f1
  2. select * from regexp_matches('2100-01-02 01:02:03','^((((19|20|21)[0-9]{2})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))\s((?:(?:([01]?[0-9]|2[0-3]):)?([0-5]?[0-9]):)?([0-5]?[0-9])))$') as f1
复制代码
把一段字符串中的冒号、单引号、问号前面加上问号 这个正则怎么写
  1. select regexp_replace('所以 font-face 规则实际上是在找到:glyphicons地方''声明? font-family 和位置','([\?'':]{1})','?\1','g')
复制代码
必须以字母开头,且长度为4-16的字符串
  1. select 'a123'~'^((?![0-9_@]+)[0-9a-zA-Z_@]{4,16})$',
  2. '0a123'~'^((?![0-9_@]+)[0-9a-zA-Z_@]{4,16})$',
  3. '@a123'~'^((?![0-9_@]+)[0-9a-zA-Z_@]{4,16})$',
  4. '_a123'~'^((?![0-9_@]+)[0-9a-zA-Z_@]{4,16})$',
  5. 'a1234567890123456'~'^((?![0-9_@]+)[0-9a-zA-Z_@]{4,16})$'
复制代码
增补:PostgreSQL 正则表达式 常用函数
对那些须要进行复杂数据处理的步伐来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述 PostgreSQL 的一些常用正则表达式函数以及源码中的一些函数。
正则干系部分的目录结构
  1. [root@localhost regex]# pwd
  2. /opt/hgdb-core/src/include/regex
  3. [root@localhost regex]# ll
  4. total 40
  5. -rw-r--r--. 1 postgres postgres 3490 Mar 19 19:00 regcustom.h
  6. -rw-r--r--. 1 postgres postgres 1332 Mar 19 18:59 regerrs.h
  7. -rw-r--r--. 1 postgres postgres 6703 Mar 19 19:00 regex.h
  8. -rw-r--r--. 1 postgres postgres 2353 Mar 19 19:00 regexport.h
  9. -rw-r--r--. 1 postgres postgres 16454 Mar 19 19:00 regguts.h
复制代码
正则表达式编译、匹配、开释、错误信息干系文件,背面再做详细先容
  1. [root@localhost regex]# pwd
  2. /opt/hgdb-core/src/backend/regex
  3. [root@localhost regex]# ll reg*.c
  4. -rw-r--r--. 1 postgres postgres 55851 Mar 19 19:00 regcomp.c
  5. -rw-r--r--. 1 postgres postgres 3671 Mar 19 18:59 regerror.c
  6. -rw-r--r--. 1 postgres postgres 34873 Mar 19 19:00 regexec.c
  7. -rw-r--r--. 1 postgres postgres 2123 Mar 19 18:59 regfree.c
  8. [root@localhost regex]#
复制代码
内置函数实如今 regexp.c
  1. [root@localhost adt]# pwd
  2. /opt/hgdb-core/src/backend/utils/adt
  3. [root@localhost adt]# ll regexp.c
  4. -rw-r--r--. 1 postgres postgres 34863 Apr 12 02:29 regexp.c
  5. [root@localhost adt]#
复制代码
内置函数声明:
  1. /* src/include/catalog/pg_proc.h */
  2. DATA(insert OID = 2073 ( substring PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "25 25" _null_ _null_ _null_ _null_ _null_ textregexsubstr _null_ _null_ _null_ ));
  3. DESCR("extract text matching regular expression");
  4. DATA(insert OID = 2074 ( substring PGNSP PGUID 14 1 0 0 0 f f f f t f i 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ "select pg_catalog.substring($1, pg_catalog.similar_escape($2, $3))" _null_ _null_ _null_ ));
  5. DESCR("extract text matching SQL99 regular expression");
  6. DATA(insert OID = 2284 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ textregexreplace_noopt _null_ _null_ _null_ ));
  7. DESCR("replace text using regexp");
  8. DATA(insert OID = 2285 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 25 "25 25 25 25" _null_ _null_ _null_ _null_ _null_ textregexreplace _null_ _null_ _null_ ));
  9. DESCR("replace text using regexp");
  10. DATA(insert OID = 2763 ( regexp_matches PGNSP PGUID 12 1 1 0 0 f f f f t t i 2 0 1009 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_matches_no_flags _null_ _null_ _null_ ));
  11. DESCR("find all match groups for regexp");
  12. DATA(insert OID = 2764 ( regexp_matches PGNSP PGUID 12 1 10 0 0 f f f f t t i 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_matches _null_ _null_ _null_ ));
  13. DESCR("find all match groups for regexp");
  14. DATA(insert OID = 2765 ( regexp_split_to_table PGNSP PGUID 12 1 1000 0 0 f f f f t t i 2 0 25 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_table_no_flags _null_ _null_ _null_ ));
  15. DESCR("split string by pattern");
  16. DATA(insert OID = 2766 ( regexp_split_to_table PGNSP PGUID 12 1 1000 0 0 f f f f t t i 3 0 25 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_table _null_ _null_ _null_ ));
  17. DESCR("split string by pattern");
  18. DATA(insert OID = 2767 ( regexp_split_to_array PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1009 "25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_array_no_flags _null_ _null_ _null_ ));
  19. DESCR("split string by pattern");
  20. DATA(insert OID = 2768 ( regexp_split_to_array PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ _null_ regexp_split_to_array _null_ _null_ _null_ ));
复制代码
参数范例及返回值范例:
  1. postgres=# select oid,typname from pg_type where oid = 25 or oid = 1009;
  2. oid | typname
  3. ------+---------
  4. 25 | text
  5. 1009 | _text
  6. (2 rows)
复制代码
  1. substring(string from pattern)
复制代码
函数提供了从字符串中抽取一个匹配 POSIX 正则表达式模式的子字符串的方法。如果没有匹配它返回 NULL ,否则就是文本中匹配模式的那部分。
  1. regexp_replace(source, pattern, replacement [, flags ])
复制代码
函数提供了将匹配 POSIX 正则表达式模式的子字符串替换为新文本的功能。
  1. regexp_matches(string, pattern[, flags ])
复制代码
函数返回一个从匹配POSIX正则表达式模式中获取的全部子串结果的text数组。
参数flags是一个可选的text字符串,含有0或者更多单字母标记来改变函数举动。标记g导致查找字符串中的每个匹配,而不仅是第一个,每个匹配返回一行。
  1. regexp_split_to_table(string, pattern[, flags ])
复制代码
函数使用POSIX正则表达式模式作为分隔符,分隔字符串。返回结果为string。。
  1. regexp_split_to_array (string, pattern[, flags ])
复制代码
函数与regexp_split_to_table举动类似,但,返回结果为text数组。
详细使用参考用户手册。
  1. src/include/regex/regex.h
复制代码
regex_t 结构体
  1. /* the biggie, a compiled RE (or rather, a front end to same) */
  2. typedef struct
  3. {
  4. int re_magic; /* magic number */
  5. size_t re_nsub; /* number of subexpressions */
  6. long re_info; /* information about RE */
  7. #define REG_UBACKREF 000001
  8. #define REG_ULOOKAHEAD 000002
  9. #define REG_UBOUNDS 000004
  10. #define REG_UBRACES 000010
  11. #define REG_UBSALNUM 000020
  12. #define REG_UPBOTCH 000040
  13. #define REG_UBBS 000100
  14. #define REG_UNONPOSIX 000200
  15. #define REG_UUNSPEC 000400
  16. #define REG_UUNPORT 001000
  17. #define REG_ULOCALE 002000
  18. #define REG_UEMPTYMATCH 004000
  19. #define REG_UIMPOSSIBLE 010000
  20. #define REG_USHORTEST 020000
  21. int re_csize; /* sizeof(character) */
  22. char *re_endp; /* backward compatibility kludge */
  23. Oid re_collation; /* Collation that defines LC_CTYPE behavior */
  24. /* the rest is opaque pointers to hidden innards */
  25. char *re_guts; /* `char *' is more portable than `void *' */
  26. char *re_fns;
  27. } regex_t;
复制代码
存放编译后的正则表达式
regmatch_t 结构体
  1. /* result reporting (may acquire more fields later) */
  2. typedef struct
  3. {
  4. regoff_t rm_so; /* start of substring */
  5. regoff_t rm_eo; /* end of substring */
  6. } regmatch_t;
  7. typedef long regoff_t;
复制代码
成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放竣事位置。通常我们以数组的情势界说一组这样的结构。
有下面几个主要的函数声明
  1. /*
  2. * the prototypes for exported functions
  3. */
  4. extern int pg_regcomp(regex_t *, const pg_wchar *, size_t, int, Oid);
  5. extern int pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *, size_t, regmatch_t[], int);
  6. extern int pg_regprefix(regex_t *, pg_wchar **, size_t *);
  7. extern void pg_regfree(regex_t *);
  8. extern size_t pg_regerror(int, const regex_t *, char *, size_t);
  9. extern void pg_set_regex_collation(Oid collation);
复制代码
处理正则表达式常用的函数有 pg_regcomp()、pg_regexec()、pg_regfree() 和 pg_regerror()。
一般处理步调:编译正则表达式 pg_regcomp(),匹配正则表达式 pg_regexec(),开释正则表达式 pg_regfree()。
pg_regerror() :当实验regcomp 或者regexec 产生错误的时间,就可以调用这个函数而返回一个包罗错误信息的字符串。
参数说明
  1. int
  2. pg_regcomp(regex_t *re,
  3.   const chr *string, /* 正则表达式字符串 */
  4.   size_t len, /* 正则表达式字符串长度 */
  5.   int flags,
  6.   Oid collation)
  7. int
  8. pg_regexec(regex_t *re, /* 已经用regcomp函数编译好的正则表达式 */
  9.   const chr *string, /* 目标字符串 */
  10.   size_t len, /* 目标字符串长度 */
  11.   size_t search_start, /* 匹配开始位置 */
  12.   rm_detail_t *details, /* NULL */
  13.   size_t nmatch, /* 是regmatch_t结构体数组的长度 */
  14.   regmatch_t pmatch[], /* regmatch_t类型的结构体数组,存放匹配文本串的位置信息 */
  15.   int flags)
复制代码
flags
  1. src/backend/utils/adt/regexp.c
复制代码
  1. /* all the options of interest for regex functions */
  2. typedef struct pg_re_flags
  3. {
  4. int cflags; /* compile flags for Spencer's regex code */
  5. bool glob; /* do it globally (for each occurrence) */
  6. } pg_re_flags;
  7. /*
  8. * parse_re_flags - parse the options argument of regexp_matches and friends
  9. *
  10. * flags --- output argument, filled with desired options
  11. * opts --- TEXT object, or NULL for defaults
  12. *
  13. * This accepts all the options allowed by any of the callers; callers that
  14. * don't want some have to reject them after the fact.
  15. */
  16. static void
  17. parse_re_flags(pg_re_flags *flags, text *opts)
  18. {
  19. /* regex flavor is always folded into the compile flags */
  20. flags->cflags = REG_ADVANCED;
  21. flags->glob = false;
  22. if (opts)
  23. {
  24. char *opt_p = VARDATA_ANY(opts);
  25. int opt_len = VARSIZE_ANY_EXHDR(opts);
  26. int i;
  27. for (i = 0; i < opt_len; i++)
  28. {
  29. switch (opt_p[i])
  30. {
  31. case 'g':
  32.   flags->glob = true;
  33.   break;
  34. case 'b': /* BREs (but why???) */
  35.   flags->cflags &= ~(REG_ADVANCED | REG_EXTENDED | REG_QUOTE);
  36.   break;
  37. case 'c': /* case sensitive */
  38.   flags->cflags &= ~REG_ICASE;
  39.   break;
  40. case 'e': /* plain EREs */
  41.   flags->cflags |= REG_EXTENDED;
  42.   flags->cflags &= ~(REG_ADVANCED | REG_QUOTE);
  43.   break;
  44. case 'i': /* case insensitive */
  45.   flags->cflags |= REG_ICASE;
  46.   break;
  47. case 'm': /* Perloid synonym for n */
  48. case 'n': /* \n affects ^ $ . [^ */
  49.   flags->cflags |= REG_NEWLINE;
  50.   break;
  51. case 'p': /* ~Perl, \n affects . [^ */
  52.   flags->cflags |= REG_NLSTOP;
  53.   flags->cflags &= ~REG_NLANCH;
  54.   break;
  55. case 'q': /* literal string */
  56.   flags->cflags |= REG_QUOTE;
  57.   flags->cflags &= ~(REG_ADVANCED | REG_EXTENDED);
  58.   break;
  59. case 's': /* single line, \n ordinary */
  60.   flags->cflags &= ~REG_NEWLINE;
  61.   break;
  62. case 't': /* tight syntax */
  63.   flags->cflags &= ~REG_EXPANDED;
  64.   break;
  65. case 'w': /* weird, \n affects ^ $ only */
  66.   flags->cflags &= ~REG_NLSTOP;
  67.   flags->cflags |= REG_NLANCH;
  68.   break;
  69. case 'x': /* expanded syntax */
  70.   flags->cflags |= REG_EXPANDED;
  71.   break;
  72. default:
  73.   ereport(ERROR,
  74.   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  75.   errmsg("invalid regexp option: "%c"",
  76.    opt_p[i])));
  77.   break;
  78. }
  79. }
  80. }
  81. }
复制代码
选项形貌
b剩余的正则表达式是 BR
c大小写敏感匹配(覆盖利用符范例)
e剩余的正则表达式是 ERE
i大小写不敏感匹配(覆盖利用符范例)
mn的汗青同义词
n新行敏感匹
p部分新行敏感匹配
q重置正则表达式为一个文本("引起")字符串,全部都是普通字符。
s非新行敏感匹配(缺省)
t紧语法
w反转部分新行敏感("怪异")匹配
x扩展的语法
以上为个人经验,盼望能给各人一个参考,也盼望各人多多支持草根技术分享。如有错误或未思量完全的地方,望不吝见教。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作