【问题标题】:java regex - searching for empty content between two occurences of a search charjava regex - 在两次出现的搜索字符之间搜索空内容
【发布时间】:2010-09-28 15:52:59
【问题描述】:

我是 Java 正则表达式的新手。

抱歉,发帖太长了。

我有三个要求:

1a) 我有一个包含三个单词“TEST”的字符串。每个单词后跟 ^ ,我需要检查 ^ 的第 2 次和第 3 次出现之间的内容是否为空白,如果是空白/空则进一步搜索以查看 ^ 的第 5 次和第 6 次出现之间的内容是否为“” 如果是“”,则将其替换为空白/空 例子: 现有字符串:

aaaa^ 
TEST^x^^y^z^""^cccc^bbb^ 

预期字符串:

aaaa^ 
TEST^x^^y^z^^cccc^bbb^ 

1b) 如果 ^ 的第 2 次和第 3 次出现之间的内容不是空白且不是 "",则不要更改第 5 次和第 6 次出现之间的内容

现有字符串:

TEST^p^^q^r^""^lll^mmm^ 

预期字符串:

TEST^p^^q^r^""^lll^mmm^

每当找到 TEST 字时,我都需要重复此逻辑检查。

1c) 如果 ^ 的第 5 次和第 6 次出现之间的内容不是空白且不是 "",并且如果第 2 次和第 3 次之间的内容为空白/空,则将其替换为 STR。

现有字符串:

TEST^g^^q^r^YYY^lll^mmm^ 

预期字符串:

TEST^g^STR^q^r^YYY^lll^mmm^ 

我需要在 Java 正则表达式中完成上述所有情况。我可以根据我之前在这个论坛上发帖的宝贵意见来制作案例 1。我无法使案例 2 和 3 工作。

如何在同一个正则表达式中完成案例 2 和 3(我不确定正则表达式用于非空 contnet 检查和“或”检查)。 在非正则表达式的世界中,在普通的 if else 方法中,我可以处理以下 3 种情况:

if (the content between 2nd and 3rd occurence of ^ is empty) 
{ 

if(content between 5th and 6th occurence of ^ is "") 
{ 
make this content empty 
} 
else 
{ 
set the content between 2nd and 3rd occurence of ^ as STR 
} 


} 

但由于我需要对字符串中以 TEST 开头的每一行进行此项检查,因此我倾向于使用正则表达式。

到目前为止,适用于案例 1 的正则表达式如下:

str.replaceAll("(TEST\\^[^^]*\\^\\^[^^]*\\^[^^]*\\^)\"\"", "$1") 

对于第二种情况,我尝试如下修改上述正则表达式,但徒劳无功(尝试在第 2 次和第 3 次出现之间搜索非空值,其中我假设 *\\d0$ 表示空,[\\d0$] 表示非空):

str.replaceAll("(TEST\\^[^^]*\\^[^\\d0$]\\^[^^]*\\^[^^]*\\^)\"\"", "$1") 

非常感谢任何帮助提出处理上述 3 个用例的正则表达式,因为我有一个截止日期来完成这项任务。

非常感谢任何帮助。

提前致谢。

【问题讨论】:

  • java regex search replace issue 的可能重复项
  • 您的 1a 和 1b 示例字符串是等价的 - 区别在哪里?像TEST^x^""^y^z^""^aaa 这样的字符串会发生什么?
  • 您可能应该编辑您的原始问题,而不是开始一个新问题。不过现在关闭可能为时已晚。
  • 你得到了很多有用的答案,别忘了接受对你最有帮助的答案(并投票给其他人)。

标签: java regex


【解决方案1】:

在我看来,^ 是一个分隔符。所以如果你只是在分隔符处拆分字符串并使用数组,它可以让生活变得更轻松:

List<String> lines = FileUtils(myFile, myEncoding);
List<String[]> allValues = new ArrayList<String[]>();
for (String line: lines)
    allValues.add(line.split("\\^"));

上面的例子展示了一种使用 apache-commons-io 处理整个 csv 文件的方法。

【讨论】:

    【解决方案2】:

    不要使用正则表达式来解析这个使用拆分例如

    var arr;
    arr=str.split("\^","g");
    

    并在结果数组中的每个适当项目上执行您描述的逻辑。

    抱歉,如果我的 java 语法不正确!

    【讨论】:

      【解决方案3】:

      我将首先尝试解决您的 (1b) 问题。很抱歉,如果 ^ IS BLANK 的第 2 次和第 3 次出现之间的内容,我想您忘记提及 (1b) 中应采取的措施。

      1b) 如果 ^ 的第 2 次和第 3 次出现之间的内容不是空白且不是 "",则在第 5 次和第 6 次出现之间不要更改内容

      【讨论】:

      • 1b 用例 - 如果是 BLANK/EMPTY,忽略。
      • 1b 用例 - 如果是 BLANK/EMPTY 则忽略 => 无需更改。
      【解决方案4】:

      我已根据您的新要求更新了代码。 ^ 和 |两者在正则表达式中都有特殊含义,因此如果您的分隔符是特殊字符之一,则需要更加小心处理。新代码是

      public class Main {
      
          public static void main(String[] args) {
              System.out.println(replace("TEST^x^^y^z^\"\"^cccc^bbb^", '^'));//case 1a
              System.out.println(replace("TEST^x^^y^z^\"\"Something^cccc^bbb^", '^'));//case 1a
              System.out.println(replace("TEST^x^^y^z^Something\"\"^cccc^bbb^", '^'));//case 1a
              System.out.println(replace("TEST^x^Something^y^z^\"\"^cccc^bbb^", '^'));//case 1b
              System.out.println(replace("TEST^x^^y^z^\"Something\"^cccc^bbb^", '^'));//case 1c
      
              System.out.println(replace("TEST|x||y|z|\"\"|cccc|bbb|", '|'));//case 1a
              System.out.println(replace("TEST|x||y|z|\"\"Something|cccc|bbb|", '|'));//case 1a
              System.out.println(replace("TEST|x||y|z|Something\"\"|cccc|bbb|", '|'));//case 1a
              System.out.println(replace("TEST|x|Something|y|z|\"\"|cccc|bbb|", '|'));//case 1b
              System.out.println(replace("TEST|x||y|z|\"Something\"|cccc|bbb|", '|'));//case 1c
          }
      
          /*
          private static String replace(String in) {
              String intermediateResult = in.replaceAll("(TEST\\^[^^]*\\^\\^[^^]*\\^[^^]*\\^)\"\"\\^", "$1^");
              String finalResult = intermediateResult.replaceAll(
                      "(TEST\\^[^^]*\\^)(\\^[^^]*\\^[^^]*\\^([^\"\\^].*|\"[^\"].*))", "$1STR$2");
              return finalResult;
          }*/
      
          private static String replace(String in, char deliminator) {
              String delim = "\\"+deliminator;
              String intermediateResult = in.replaceAll(
                      "(TEST" + delim +
                      "[^" + delim + "]*" +
                      delim + delim +
                      "[^" + delim + "]*" + delim +
                      "[^" + delim + "]*" + delim +
                      ")\"\"" + delim,
                      "$1"+deliminator);
      
              String finalResult = intermediateResult.replaceAll(
                      "(TEST" + delim +
                      "[^" + delim + "]*" 
                      + delim + ")(" + delim +
                      "[^" + delim + "]*" + delim +
                      "[^" + delim + "]*" + delim +
                      "([^\"" + delim + "].*|\"[^\"].*))", "$1STR$2");
              return finalResult;
          }
      }
      

      输出是

      TEST^x^^y^z^^cccc^bbb^
      TEST^x^^y^z^""Something^cccc^bbb^
      TEST^x^STR^y^z^Something""^cccc^bbb^
      TEST^x^Something^y^z^""^cccc^bbb^
      TEST^x^STR^y^z^"Something"^cccc^bbb^
      TEST|x||y|z||cccc|bbb|
      TEST|x||y|z|""Something|cccc|bbb|
      TEST|x|STR|y|z|Something""|cccc|bbb|
      TEST|x|Something|y|z|""|cccc|bbb|
      TEST|x|STR|y|z|"Something"|cccc|bbb|
      

      【讨论】:

      • 谢谢。我不想问,但是 ^ 与搜索字符串 ^ 的意义是什么。当搜索字符为 ^ 时它工作正常,但当搜索字符为 | 时失败(我试过 \\| 但徒劳无功)。我的意思是在这种情况下我也需要让它工作 - TEST|x||y|z||cccc|bbb|。提前致谢。
      • 在搜索文字为 | 的情况下,我尝试使正则表达式适用于 1a 场景 (TEST|x||||""|ccc|)但必须执行以下操作:String intermediateResult = in.replaceAll( "(TEST\\\\|[\\|\\|]*\\\\|\\\\|[\\|\\|]* \\\\|[\\|\\|]*\\\\|)\"\"\\|", "$1\\|" );但是如果我使用 \\| 则它不起作用...我不明白为什么它需要 \\\\|搜索文字?鉴于我的截止日期,我希望我有足够的时间来更好地理解正则表达式。
      • 还有 - 的 |当第 5 次出现的内容有 xx"" 时,方法不起作用。它必须忽略它,但它正在删除“”。在其他情况下-“”xxx-它不会改变它,这是正确的方法。我的要求是仅当内容在搜索文字的第 5 次和第 6 次出现之间只有“”时才删除“”|非常感谢任何帮助以了解我哪里出错了......我希望我有足够的时间在我的最后期限内更好地使用正则表达式。
      • 我尝试了几件事,但徒劳地讨厌放弃,但由于时间/期限限制,我想请您了解如何使替换在最初提到的所有三种情况下工作搜索文字是 |而不是 ^ 非常感谢您的帮助,因为没有其他帮助可以寻找,因为我们工作中的所有人都是正则表达式的新手,并且考虑到这个生产问题/截止日期的时间限制。提前致谢。
      • 这是指您发送的第二个 replaceall - 我无法理解 .*|\" 在您在第二个正则表达式模式([^\"\ \^].*|\"[^\"].*))。我正在尝试为 | 制作您的正则表达式模式而不是 ^ (根据我的其他要求)但徒劳无功......我错过了一些话,如果 | 第 5 次出现包含除“”或空/空白以外的内容,替换 | 的第二次和第三次出现之间的 EMPTY 内容非常感谢任何帮助。谢谢!
      猜你喜欢
      • 2021-04-29
      • 2022-01-11
      • 2013-05-06
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      相关资源
      最近更新 更多