有如下数据
a.b
a.b.c要求把这些数据分差成两部分,如
part1  part2
a      b
a      b.c我写的是这样一个匹配表达式, (\w+)\.(.*)
取出来却是,“.”匹配的是最后一个位置
part1  part2
a      b
a.b    c求大家指点!

解决方案 »

  1.   

    正则表达式不会写,寻求一个简单的方法:
        select                                      
            substr('a.b.c',1,instr('a.b.c','.')-1)  
           ,substr('a.b.c',instr('a.b.c','.',1,1)+1)
         from dual;   
    结果:
    a
    b.c          
      

  2.   

    SELECT REGEXP_SUBSTR('a.b.c', '(^.)|((\.)(.)+)', LEVEL)
      FROM DUAL
    CONNECT BY LEVEL <= 2;结果:
    a
    .b.c
    SELECT REGEXP_REPLACE('.b.c','^.','') FROM DUAL;结果
    b.c
    倒是有一个方法可以直接得到b.c  但是一下子想不起来了
      

  3.   

    这里有转一篇写的非常好的正则表达式的使用,看完之后对正则的理解能有突飞猛进的效果:摘自ITPUB:  正则表达式具有强大、便捷、高效的文本处理功能。能够添加、删除、分析、叠加、插入和休整各种类型的文本和数据。Oracle从10G开始支持正则表达式。
      下面是通过一些例子来说明使用正则表达式来处理一些工作中的常见问题。1. REGEXP_SUBSTR
      REGEXP_SUBSTR函数使用正则表达式来指定返回串的起点和终点,返回与source_string字符集中的VARCAHR2或者CLOB数据相同的字符串。
    语法结构如下:
    --1.REGEXP_SBUSTR与SUBSTR函数相同,返回截取的子字符串。
    REGEXP_SUBSTR(srcstr,parttern[,position[,occurrence[,match_option]]]
    注:
    srcstr:源字符串
    pattern:正则表达式样式
    position:开始匹配字符位置
    occurrence:匹配出现的次数
    match_option:匹配选项(区分大小写)1.1 从字符串中截取子字符串
    SELECT REGEXP_SUBSTR('1PSN/231_3253/ABc','[[:alnum:]]+') AS R_STR FROM DUAL;
    分析:这个结果是1PSN,里面的[[:alnum:]]+表示一个或者多个字母或者数字字符.SELECT REGEXP_SUBSTR('1PSN/231_3253/ABc','[[:alnum:]]+',1,2) AS R_STR FROM DUAL;
    分析:这个结果是231与上面第一个例子做比较,多了两个参数,第一个参数表示从源字符串的第一个字符开始查找匹配,第二个参数表示第二次匹配到的字符串(如果第二个参数啥也不写的话,系统默认的是1).SELECT REGEXP_SUBSTR('@@/231_3253/ABc','@*[[:alnum:]]+') AS R_STR FROM DUAL;
    分析:这个SQL的查询结果是231,刚刚看到这个SQL的时候还有一点不理解,为什么答案会是这个呢?按理说应该查询不出来才对,问题就出在*号和+号上面,在这里@*匹配0个或者多个@,[[:alnum:]]+匹配一个或者多个字母或者数字字符.这里应该非常注意*号和+号的区别.再看下面的这个例子SELECT REGEXP_SUBSTR('1@/231_3253/ABc','@+[[:alnum:]]*') AS R_STR FROM DUAL;
    分析:上面的这个SQL的执行结果就是@,为什么呢?这里@+代表一个或者多个@,[[:alnum:]]*表示零个或者多个字符或者数字字符.SELECT REGEXP_SUBSTR('1@/231_3253/ABc','@+[[:alnum:]]+') AS R_STR FROM DUAL;
    分析:上面的这个SQL的执行结果是空,这里@+代表一个或者多个@,[[:alnum:]]+代表一个或者多个字符或者数字的,所以,这个查询结果就是空了.SELECT REGEXP_SUBSTR('@1PSN/231_3253/ABc123','[[:digit:]]+$') AS R_STR FROM DUAL;
    分析:上面的这个SQL的执行结果是123,在正则表达式里面,增加一个$代表的就是结尾的意思,[[:digit:]]+$表示匹配的一个或者多个结尾的数字字符.SELECT REGEXP_SUBSTR('@1PSN/231_3253/123ABc','[^[:digit:]]+$') AS R_STR FROM DUAL;
    分析:上面的这个SQL的执行结果是ABc,在正则表达式里面增加^符号,代表的就是排除的意思.[^[:digit:]]+$代表的是不为数字结尾的字符.SELECT REGEXP_SUBSTR('@1PSN/231_3253/123ABc','[[:alnum:]]*',1,LEVEL) AS R_STR FROM DUAL CONNECT BY LEVEL<=10;
    分析:这个SQL可以好好的研究一下,执行结果比较怪异,里面的[[:alnum:]]*表示的是匹配零个或者多个字母或者数字的字符.来模拟一下这个过程,第一次匹配的时候,发现是@,因此得到的是空,第二次得到的是1PSN然后是/得到的是空....1.2 匹配重复出现
    查找连续2个小写字母
    SELECT REGEXP_SUBSTR('Republicc Of Africaa','([a-z])\1',1,1,'i') AS r_str FROM dual;
    分析:这个SQL的结果是cc,([a-z])表示的小写字母a-z,里面匹配的\1表示匹配前面的字符的连续次数(这个地方不是说出现1次,其实是这样样子的\1\1表示加上本身连续出现三次,\1表示加上本身连续出现两次).1表示从源字符串的第一个字符开始匹配,1第一次出现符合匹配结果的字符,i表示区分大小写.连续查找3个6,7,8,9中的数字
    SELECT CASE
      WHEN REGEXP_LIKE('Patch 10888 applied','([6-9])\1\1') THEN
      'Match Found'
      ELSE
      'No Match Found'
      END AS OUTPUT
    FROM DUAL;1.3其他一些匹配样式
    查找网页地址信息
    Select regexp_substr('Go to http://www.oracle.com/products and click on database','http://([[:alnum:]]+\.?){3,4}/?') r_str
    from dual;
    分析:上面的([[:alnum:]]+\.?)表示匹配的是一次或者多次的字母或者数字字符,紧跟零次或者一次逗号.{3,4}表示匹配前面的字符,最少三次,最多四次./?表示匹配一个反斜杠零次或者一次.提取csv字符串的第三个值
    select regexp_substr('1101,Yokohama,japan,1.5.105','[^,]+',1,3) as r_str from dual;
    分析:[^,]+表示匹配一个或者多个不是逗号的字符,1表示从源字符串的第一个字符开始查找匹配,3表示第三个匹配到的字符串.下面的例子,查找源字符串中是否包含kid,kids或者kidding这三个字符串:
    SELECT CASE when regexp_like('Why does a kid enjoy kidding with kids only?','kid(s|ding)*','i')THEN
    'Match Found'
    else
    'No Match Found'
    End as r_str
    from dual;
    分析:上面的SQL输出的结果是Match Found.kid表示字符串kid,(s|ding)*表示匹配0此或者多次字符串s或者ding,i表示不区分大小写.
     
    2.REGEXP_INSTR
    REGEXP_INSTR函数使用正则表达式返回搜索模式的起点.REGEXP_INSTR的语法如下所示.REGEXP_INSTR返回一个整数,该整数指出搜索模式的开始或者结束的位置,如果没有发现匹配的值的话,就返回0.语法如下:
    --2. REGEXP_INSTR 与INSTR的函数相同,返回字符串的位置
    REGEXP_INSTR(srcstr,pattern[,position[,occurrence[,return_option[,match_option]]]])
    与REGEXP_SUBSTR一样,REGEXP_INSTR也有变量pattern,position(开始位置),occurrence和match_parameter,这里主要介绍一下新的参数return_option的作用,这个return_option告诉Oracle模式出现的时候,要返回什么内容.具体的可以看下面的例子:SELECT REGEXP_INSTR('abc111defg','[[:digit:]]') r_str from dual;
    上面的这个结果就是返回的是4,因为第一次出现数字的时候,是第四个.SELECT REGEXP_INSTR('abc1defg','[[:digit:]]',1,1,1) s_str from dual;
    上面的这个结果返回的是5,因为第三个参数表示的是return_mode,这个地方如果是1指的是,得到出现了符合正则表达式后面的一个字符的位置.在当前的这个字符串中,第一个出现数字的是第四位,因此返回的结果就为五了.3.REGEXP_LIKE
    出了上面的正则表达式函数,还可以使用REGEXP_LIKE函数.REGEXP_LIKE支持在where子句中使用正则表达式.
    语法如下:
    REGEXP_LIKE与LIKE函数相同,返回布尔类型
    REGEXP_LIKE(srcstr,pattern[,match_option])3.1 验证字符串全部由字母组成
    SELECT CASE WHEN
      REGEXP_LIKE('Google','^[[:alpha:]]{6}$') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的这个SQL的结果是Matched Found,在这个^[[:alpha:]]{6}$正则表达式里面,^表示的是正则表达式行的开始,[[:alpha:]]表示字母,{6}表示匹配的次数,这里表示匹配6次,$表示行的结尾.3.1 验证字符串全部由小写字母组成
    SELECT CASE WHEN
      REGEXP_LIKE('google','^[[:lower:]]{2,12}$') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的这个SQL的结果是Matched Found这个例子同上面一个,只是[[:lower:]]匹配的是小写字母.上面的{2,12}表示最少匹配2次,最多匹配12次.3.3 区分大小写
    SELECT CASE WHEN
      REGEXP_LIKE('Republic Of China','of','c') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的这个SQL的结果是No Matched Found,通过正则表达式来看这个字符串中是否存在字符串of,后面的c表示的是区分大小写,必须完全匹配.
    SELECT CASE WHEN
      REGEXP_LIKE('Republic Of China','of','i') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    这个SQL的结果就是Matced Found了,因为我们将c修改为i,i的意思是忽略大小写.3.4 匹配第n个位置的字符
    SELECT CASE WHEN
      REGEXP_LIKE('ter*minator','^...[^[:alnum:]]') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    这个SQL的结果是Matched Found解释一下^...[^[:alnum:]]其中:^表示行的开始,里面的.表示匹配任意一个的字符(...表示三个任意的字符)[^[:alnum:]]表示既不是字母也不是数字的字符(^在方括号里面,表示的是否定,如果是放在方括号外面,表示的是非)3.5查找控制字符
    SELECT CASE WHEN
      REGEXP_LIKE('Supper'||chr(13)||'star','[[:cntrl:]]') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的这个SQL返回的结果是Matched Found,通过正则表达式来验证字符串里面是否包含控制符(char13在ASCII码中表示回车符)3.6 验证SSN
    SELECT CASE WHEN
      REGEXP_LIKE('123-212-124-14','^([0-9]){3}-([0-9]){3}-([0-9]){3}-([0-9]){2}$') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的SQL的返回结果是Matched Found,分析一下这个正则表达式,里面的^表示正则表达式行的开始,$表示正则表达式行的结束,([0-9]){3}表示连续出现三次0到9的数字,-表示连字号-.3.7 验证email地址
    SELECT CASE WHEN
      REGEXP_LIKE('[email protected]','^([[:alnum:]]+(_?|\.)*)[[:alnum:]]*@[[:alnum:]]+(\.([[:alnum:]]+)){1,2}$') THEN
      'Matched Found'
      ELSE
      'No Matched Found'
      END AS R_STR
    FROM DUAL
    上面的SQL返回的结果是Matched Found.在正则表达式里面出现的\符号表示的是转义符的意思,因为.是关键字,能够匹配任意字符,因此需要进行转义.4. REGEXP_REPLACE
    REGEXP_REPLACE函数是用另外一个值来替代串中的某个值.例如,可以用一个匹配的数字来代替字母的每一次出现,REGEXP_REPLACE函数的语法格式如下面所示:
    --4. REGEXP_REPLACE与REPLACE函数相同,用于替换源字符串中的字符内容
    REGEXP_REPLACE(srcstr,pattern[,replacestr[,postition[,occurrence[,match_option]]]])4.1 查找替换空格符
    SELECT REGEXP_REPLACE('Help Earth Stay Green','[[:blank:]]{1,8}','') from dual;
    上面的SQL返回的结果是HelpEarthStayGreen,等于去掉了空格字符。[[:blank:]]表示空格字符,{1,8}表示的是出现的次数,最少一次,最多8次.4.2 格式化字符串
    SELECT REGEXP_REPLACE('04099661234','([[:digit:]]{3})([[:digit:]]{4})([[:digit:]]{4})','(\1) \2-\3') AS FORMATTED_PHONE
    FROM DUAL;
    ([[:digit:]]{3})表示三个数字 \1
    ([[:digit:]]{4})表示三个数字 \2
    所以,(\1)\2-\3表示将前面三个数字用圆括号,紧跟着一个空格,再跟着四个数据,再跟着连字符"-",最后是后四位的数字更多格式化字符串的例子
    SELECT REGEXP_REPLACE('04099661234','^([[:digit:]]{1})([[:digit:]]{2})([[:digit:]]{4})([[:digit:]]{4})$','+91-\2-\3-\4') 
    FROM DUAL
    下面的例子,在每两个字符之间插入一个空格:
    SELECT REGEXP_REPLACE('chenzw','(.)','\1 ') FROM DUAL5.附录5.1元字符* 匹配零次或者多次出现
    + 匹配一次或者多次出现
    ? 匹配零次或者一次出现
    ^ 匹配行的开始字符
    $ 匹配行的结束字符
    . 匹配任意一个字符(除了NULL)
    \ 反斜杠字符根据上下文有四种不同的含义.它可以表示本身,引用下一个字符,引入一个运算符或者什么都不做
    [] 方括号表示指定一个匹配列表,该列表匹配列表中显示的任何表达式
    [^] 同上面的相反,非匹配列表表达式
    () 分组表达式,可以看做单个子表达式
    {m} 匹配m次
    {m,} 至少匹配m次
    {m,n} 至少匹配m次,但是不能超过n次
    [::] 指定字符类,例如:[:alpha:],可以匹配字符类中的任何字符
    [==]指定等价类,例如[=a=]匹配所有包含基本字母"a"的字符5.2匹配选项i 用于不区分大小写的匹配
    c 用于区分大小写的匹配
    n 允许据点(.)作为匹配符去匹配换行符.如果省略该参数,该据点将不匹配换行符
    m 将源字符串视为多行.即Oracle将"^"和"$"分别看做源字符串中任意位置任何行的开始和结束,而不是仅仅看做整个字符串的开始或者结束.如果省略该参数,则Oracle将源字符串看做一行5.3字符类[:alnum:] 所有的字母和数字字符
    [:alpha:] 所有的字母字符
    [:blank:] 所有的空格字符
    [:cntrl:] 所有的控制字符(不会打印出来)
    [:digit:] 所有的数字
    [:graph:] 所有的[:punct:][:upper:][:lower:]和[:digit:]字符
    [:lower:] 所有的小写字母
    [:print:] 所有可打印的字符
    [:punct:] 所有的标点符号
    [:space:] 所有的空格字符(不会打印出来)
    [:upper:] 所有的大写字母
    [:xdigit:] 所有有效的十六进制字符
      

  4.   

    谢谢!但是格式可能更复杂就不还处理了
    比如:QUESTION.1.aaabbcc  点之前的长度是不固定的
      

  5.   


    SELECT regexp_substr('QUESTION.1.aaabbcc','^[^.]*') FROM dual;
    结果:
    REGEXP_SUBSTR('QUESTION.1.AAAB
    QUESTION
      

  6.   


    这样好像还不能适用于所有的情况。
    我这边的数据是这样的
    Xxx.xxx.xxx.xx
    有些部分可选,要求是以左起第一个 "."为分隔处,分成两部分