【问题标题】:java regular expression and replace all occurrencesjava正则表达式并替换所有出现
【发布时间】:2021-07-25 19:47:53
【问题描述】:

我想用一个大字符串替换一个字符串,但我猜我的正则表达式不正确。所以它不起作用。

主字符串是

一些需要替换的sql部分

cond =  emp.EMAIL_ID = 'xx@xx.com' AND
emp.PERMANENT_ADDR LIKE('%98n%') 
AND hemp.EMPLOYEE_NAME = 'xxx' and is_active='Y'

要查找和替换的字符串是

根据某些条件sql部分被替换

hemp.EMPLOYEE_NAME = 'xxx'

我已经尝试过

Pattern 和 Matcher 类被使用和

Pattern pat1 = Pattern.compile("/^hemp.EMPLOYEE_NAME\\s=\\s\'\\w\'\\s[and|or]*/$", Pattern.CASE_INSENSITIVE);
        
        Matcher mat = pat1.matcher(cond);
         while (mat.find()) {
                     System.out.println("Match: " + mat.group());
                    cond = mat.replaceFirst("xx "+mat.group()+"x");
                    mat = pat1.matcher(cond);
        
        }

它不起作用,根本没有进入循环。任何帮助表示赞赏。

【问题讨论】:

    标签: java regex replace


    【解决方案1】:

    显然不是 - 您的正则表达式模式没有任何意义。

    • 开头/:在某些语言中,正则表达式不是字符串,而是以开头的斜杠开头。 Java 不是其中一种语言,它与正则表达式本身无关。因此,这会在该 SQL 中查找文字斜杠,但该斜杠不存在,因此失败。
    • ^ 是“字符串开头”的正则表达式。您的字符串不以 hemp.EMPLOYEE_NAME 开头,因此这也不起作用。在这里去掉 / 和 ^。
    • \\s 是一个空白字符(有很多空白字符 - 这与其中任何一个匹配,但正好是一个)。您的字符串没有任何空格。当然,您的意图是 \\s* 与其中许多匹配 0,即:\\s* 是:“此处允许空格”。 \\s 是:这里必须有一个空格字符。将正则表达式中的所有\\s 设为\\s*
    • \\w 恰好是一个“单词”字符(或多或少是一个字母或数字),您显然想要\\w*
    • [and|or] 这是正则表达式:“An a, or an n, or a d, or an o, or an r, or a pipe symbol”。显然,您正在寻找(and|or),它是正则表达式:序列“and”或序列“or”。
    • * - 所以你想要 0 到多个 'and' 或 'or',这是没有意义的。
    • 结束斜线:你不想要这个。
    • 关闭$:你不想要这个——它的意思是'字符串结束'。你的字符串没有在这里结束。

    代码本身:

    replaceFirst 本身也执行正则表达式。你不想双重应用这些东西。这不是替换找到的结果的方式。

    这就是你想要的:

    Matcher mat = pat1.matcher(cond);
    mat.replaceFirst("replacement goes here");
    

    如果您想获取匹配的部分内容,替换可以包括对匹配组的引用(即不要使用mat.group(),使用这些引用)。

    更一般地说,您是否阅读过任何正则表达式教程、做过任何测试或阅读过 PatternMatcher 的 javadoc?

    我已经开发了几年。这可能只是个人经验,但是,阅读是非常基础的。

    【讨论】:

      【解决方案2】:

      除了锚点^$,您可以使用字边界\b 来防止部分匹配。

      如果要匹配同一行的空格,可以使用\h 匹配水平空白字符,因为\s 也可以匹配换行符。

      您可以使用$0 对字符串使用replaceFirst 以获得完整匹配,并使用内联修饰符(?i) 进行不区分大小写的匹配。

      注意,使用 [and|or]character class 匹配列出的字符之一并转义点以匹配它的字面意思,否则 . 匹配除换行符以外的任何字符。

      (?i)\bhemp\.EMPLOYEE_NAME\h*=\h*'\w+'\h+(?:and|or)\b
      

      查看regex demoJava demo

      例如

      String regex = "\\bhemp\\.EMPLOYEE_NAME\\h*=\\h*'\\w+'\\h+(?:and|or)\\b";
      String string = "cond =  emp.EMAIL_ID = 'xx@xx.com' AND\n"
      + "emp.PERMANENT_ADDR LIKE('%98n%') \n"
      + "AND hemp.EMPLOYEE_NAME = 'xxx' and is_active='Y'";
      
      System.out.println(string.replaceFirst(regex, "xx$0x"));
      

      输出

      cond =  emp.EMAIL_ID = 'xx@xx.com' AND
      emp.PERMANENT_ADDR LIKE('%98n%') 
      AND xxhemp.EMPLOYEE_NAME = 'xxx' andx is_active='Y'
      

      【讨论】:

      • 谢谢。如果最后没有空格或and|or怎么匹配?​​
      • 在 hemp.EMPLOYEE_NAME = 'xxx' 之后可能什么都没有。然后这个正则表达式不起作用。怎么办?
      • @mou 您可以将最后一部分设为可选(?i)\bhemp\.EMPLOYEE_NAME\h*=\h*'\w+'(?:\h+(?:and|or)\b)?regex101.com/r/v94K6v/1
      • 它在 regx 编辑器中工作,但在索引 26 (?i)\bhemp\.EMPLOYEE_NAME\h*=\h*'\w+'(?:\h+(?:和|或)\b)?在爪哇。当我用 \s 替换它时,它不起作用。
      • 是的模式和java代码都有效..我误解了动态数据并认为它不起作用..非常感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多