淘客熙熙

主题:文问题,关于正则表达式 -- pastebt

共:💬26 🌺8 新:
分页树展主题 · 全看首页 上页
/ 2
下页 末页
  • 家园 文问题,关于正则表达式

    对于字符串“1234a5635367312b563789”,怎么只替换掉a和b之间的3

    • 家园 使用零宽断言(答案)

      (?<=a\w*)3(?=\w*b)

      • 家园 两个问题

        1.在python里,positive lookbehind assertion 只能匹配定长的字串,我看你给的连接里,没有说明,而且是.net的,没用过,所以有这么一问

        2.我给的问题里,a和b之间的3是多于一个的,这也正是问题麻烦的地方。但是我没看出你的回答里是怎么解决的,能说明一下么?

        要知道,问题里的例子只是为了说明问题,并不是要真的处理那个字串,而且我也只是觉得我自己的做法(类似铁手的)不够纯粹,想钻一下牛角尖而已。谢谢

        • 家园 不同的平台对正则表达式支持的确不同

          如果零宽断言(Positive and Negative Lookahead)支持能变长匹配的话,如.NET,我上述的表达式可以匹配任意多的字符。考虑一下正则表达式的实现方法就明白了,其实我匹配的是‘3’,然后让正则引擎在找到‘3’这个字符之后去检查左右的边界是否符合要求,即两个零宽断言。由于左边界是a\w*——a开始的任意字符,右边界是\w*b——b结尾的任意字符。所以a开始和b结束之间的3都匹配。你可能被一般的搜索思路干扰了,正则表达式不是找到边界后去匹配边界中的字符,而是找到字符后去匹配边界。这就解释了第二个问题。

          第一个问题就没办法解决了,你可以看看这个连接

          外链出处,目前只有两个平台支持变长的匹配。

          • 家园 谢谢,在python里面也弄出来了

            re.split("3(?=[^a]*b)", "132a43534b34a234234b345")

            ['132a4', '5', '4b34a2', '42', '4b345']

            • 家园 不用正则也不错啊。

              问题的逻辑比较清楚。先判断a出现后,然后直到b出现之前的3都不要,就可以了。

              代码参见 http://paste.pocoo.org/show/134757/

              我也贴在下面一份,不熟悉如何在西西河设置代码格式了。

              def replace(line, start = 'a', end = 'b', source = '3', target = ''):

              IN = False

              for ch in line:

              if ch == start:

              if not IN:

              IN = True

              yield ch

              elif ch == end:

              if IN:

              IN = False

              yield ch

              elif ch == source and IN:

              yield target

              else:

              yield ch

              def main():

              line = '1234a5635367312b563789'

              print ''.join(list(replace(line)))

              if __name__ == "__main__":

              main()

              ## output 1234a5656712b563789

              关键词(Tags): #Python
            • 家园 这个有BUG吧?

              >>> re.split("3(?=[^a]*b)", "132a43534b34a234234b345b")

              ['132a4', '5', '4b34a2', '42', '4b', '45b']

              最后一个3没在a和b中间,也给滤掉了

      • 家园 推荐一个学习正则表达式的连接

        外链出处

        个人看法,正则表达式上手倒不会很难,然而其表达式可读性却非常差。因此实际使用中的困难在于如何维护这种可读性极差的正则代码。(它的确是一种代码,一种字符串匹配程序的代码)

        我的方法是采用结构化方式,一层层剥下来。比如楼主的问题可以分成三块:

        1、a开始的边界条件

        2、匹配字符3

        3、以b结束的边界条件

        这样可以一个复杂的匹配就被分解成若干个简单的匹配,写起来也就简单很多了。和写程序一样,如果第一次分解还得不出可以立即翻译的正则表达式,我们还可以进一步分解。

        而在实际代码中我就会使用字符串模板替换来还原上述过程。其伪代码很像这样:

        REG := LEFT_BORDER + MATCH_CHAR + RIGHT_BORDER

        LEFT_BORDER=.....

        MATCH_CHAR=3

        RIGHT_BORDER=.....

        怎么样?看起来有点熟悉吧。这就是大多数计算机文献中语法定义的格式。

    • 家园 你是不是想只用一个正则表达式来做这次替换?

      perl正则表达式里头有种特殊的括号:

      (?=...)

      True if lookahead assertion succeeds.

      (?!...)

      True if lookahead assertion fails.

      (?<=...)

      True if lookbehind assertion succeeds.

      (?<!...)

      True if lookbehind assertion fails.

      可以满足你的要求. 查一下programming perl的table 5.6吧.

      写这种正则表达式挺费脑子的, 我就不写例子了

    • 家园 有一个问题,确定字串中只有一个a和一个b么?

      如果有多个a,b出现,是不是还需要考虑greedy matching的问题?

    • 家园 刚想了一下,呵呵

      至少要用两次正则吧。

      实际上替换掉a和b之间的3包含两次正则,

      1、从字符串里找到a和b之间的串;2、找到3;

      而正则好像是没办法做嵌套的。

      下面是java的

      String s = "1234a5635367312b563789";

      Pattern pattern = Pattern.compile(".*?[a](.*?)[b].*?");

      Matcher matcher = pattern.matcher(s);

      if(matcher.find()){

      System.out.println(matcher.group(1).replaceAll("3","##"));

      }

      呵呵。我想就算是有一步实现的,本质上也应该是一样的,顶多封装一下。

    • 家园 java实现

      1、a和b之间的

      2、3

      应该是两次正则吧。

      java的

      String s = "1234a5635367312b563789";

      Pattern pattern = Pattern.compile(".*?[a](.*?)[b].*?");

      Matcher matcher = pattern.matcher(s);

      if(matcher.find()){

      System.out.println(matcher.group(1).replaceAll("3","##"));

      }

    • 家园 这个大概要用到Back reference

      select regexp_replace('123a235bxyza789325b345', 'a([^3]*)3([^b]*)b', 'a\1\2b', 1, 0) result from dual

      RESULT

      ----------------------------------------

      123a25bxyza78925b345

      这个是ORACLE的SQL正则

      关键词(Tags): #正则表达式
分页树展主题 · 全看首页 上页
/ 2
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河