【问题标题】:Replace zeros to letter "o" inside words将零替换为单词中的字母“o”
【发布时间】:2017-06-19 09:46:26
【问题描述】:

在 ocr 识别之后,我有很多词,而不是 o 我有 0。所以我想替换任何零inside 字。

到目前为止,我只能做以下事情

String result ="I don't like th0se books";
result = result.replaceAll("\\w+0\\w*", "o");
System.out.println("RESULT:" + result);

我的代码返回RESULT:I don't like o books,但我需要RESULT:I don't like those books。谁能告诉我怎么做?

【问题讨论】:

  • .replaceAll("(?:(?<=\\p{L})|\\G(?!\\A))0", "o")(本例不涉及首词位置)。
  • @WiktorStribiżew 你为什么不提供答案而不是评论。因为你擅长正则表达式相关的问题?
  • @Wiktor Stribiżew 您的解决方案是唯一适用于I like th0se b00ks with more that 100 pages 的解决方案。做出回答,我会接受的。
  • “而且这个问题并不准确”这就是“过于广泛”的近距离投票和反对票的原因。
  • 大多数情况下您的解决方案是可以接受的。我看过很多你的回答

标签: java regex string


【解决方案1】:

使用非单词边界:

result = result.replaceAll("\\B0|0\\B", "o");

确保在 0 之前或之后至少有一个单词字符。

如果你想防止数字内的零被替换:

result = result.replaceAll("\\b(?!\\d+\\b)(?:0\\B|([^\\W0]+)0)|\\G(?!\\A)0", "$1o");

详情:

\\b              # a word boundary
(?!\\d+\\b)      # negative lookahead: not followed by an integer
(?:
    0\\B         # zero and a non-word boundary (means a word character follows)
  |
    ([^\\W0]+)0  # word characters without zero and a zero
)
|
\\G(?!\\A)0  # a zero contiguous to a previous match (not at the start of the string)

(显然,正则表达式模式无法区分孤立的“0”和孤立的“o”,或参考编号中的“0”和“o”,或科学记数法)


其他方式:俘虏所有对手

result = result.replaceAll("((?>(?:[\\W_]+|\\pL+|\\b\\d+\\b)*))(?:\\B0|0\\B)", "$1o");

【讨论】:

  • 不幸的是,这也将 127610127 替换为 12761o127
  • @MarkusBenko:没有了。
  • 对于这个字符串:"I like th0se b00ks with more than 100 pages"; 结果将是:I喜欢那些超过 1oo 页的书
  • @ΦXocę웃Пepeúpaツ:请刷新页面。
  • “我喜欢那些书……100页”我喜欢那些书……100页
【解决方案2】:

正则表达式应该是"0" 而不是"\\w+0\\w*"

另外,要保留其余单词,请使用捕获组:result = result.replaceAll("(\\w+)0(\\w*)", "$1o$2");

仅在“字母”之间替换并忽略要求的数字:result = result.replaceAll("([a-zA-Z]+)0([a-zA-Z\s0]+)", "$1o$2");

【讨论】:

    【解决方案3】:
    (\B0\B|\B0|0\B)
    

    匹配三种情况:

    • 0 在单词中间,例如“那个”
    • 0 在词尾,例如“盖子0”
    • 0 在单词的开头,例如“0thers”

    所以,`result.replaceAll("(\B0\B|\B0|0\B)", "o");

    不过,这也会将I have 101 dogs 替换为I have 1o1 dogs,因此您可能需要进一步完善您的表达式或逻辑。

    虽然可以编写一个正则表达式来实现这一点,但我觉得用普通的Java代码来实现它会更简单、更清晰:

    • 将行拆分为标记(标记可以是一大块空白或一大块非空白 - 您可以使用正则表达式 (\s+|\S+)Matcher 捕获这些。
    • 对于每个令牌:
      • 如果是空格,不要管它
      • 如果它完全由数字和符号组成,不要理会
      • 否则word.replace('0','o')
      • 输出令牌

    【讨论】:

      【解决方案4】:

      如果您不想使用复杂的正则表达式,您可以遍历字符串并执行相同的操作。

      char c[] = new char[s.length()];
      for(int i=0;i<s.length();i++){
          if(s.charAt(i) == '0'){
              c[i] = 'o';
          }else{
              c[i] = s.charAt(i);
          }
      }
       //now convert to string.
      s = String.valueOf(c);
      

      并且仅在words 内,您可以检查以下内容:

          String s = "I like th0se b00ks ... 100 pages";
          char c[] = new char[s.length()];
          for(int i=1;i<s.length()-1;i++){
              if(s.charAt(i) == '0' && !Character.isDigit(s.charAt(i+1)) && !Character.isDigit(s.charAt(i-1))){
                  c[i] = 'o';
              }else{
                  c[i] = s.charAt(i);
              }
          }
      
          //check corner conditions.
          if(s.length() >=1 && !Character.isDigit(s.charAt(1)) && s.charAt(0) == '0'){
              c[0] = 'o';
          }
      
          if(s.length() >= 2 &&!Character.isDigit(s.charAt(s.length()-2)) && s.charAt(s.length()-1) == '0'){
              c[s.length()-1] = 'o';
          }
      
          //now convert to string.
          s = String.valueOf(c);
          System.out.println(s);
      

      【讨论】:

      • 对答案投反对票,甚至不提原因:(
      • 这是进行简单替换的一种不必要的复杂方法,并且完全忽略了 OP 的要求,即他们只想替换 0 在单词中
      • @khelwood 对于专家来说这可能是一种复杂的方式。但我认为这是最简单的方法。它完全按照 OP 的要求做。
      • 是的,我同意它使用了一个额外的数组。但时间复杂度与正则表达式相同:stackoverflow.com/questions/4378455/…
      • 1) 你跳过第一个和最后一个字符 2) 你不检查每个数字字符(这不限于 '0 ' 到 '9') 3) #0 是否被视为一个词?
      【解决方案5】:

      试试:result = result.replaceAll("(\\w+)0(\\w+)", "$1o$2");

      使用输入:“我不喜欢这些书 00 1230”

      你会得到:“我不喜欢那些书 00 1230”

      编辑:

      如果您使用:result = result.replaceAll("([a-zA-Z]+)0([a-zA-Z]+)", "$1o$2");,它也应该适用于“我不喜欢 th0se books 00 1230 1230456”字符串。

      【讨论】:

      • 重复答案
      • 我喜欢您将 * 更改为 + 但另一方面,我开始想知道代码的原始问题是什么。例如,当 OCR 匹配 P00H 时,期望的行为应该是什么?我只能停下来思考,想知道模糊的问题陈述代表了什么。
      • 1230456一样破坏其中包含零的数字。
      • 是的。我没有考虑到这一点。但也许——正如你所指出的——正确的答案取决于使用该算法的需要。
      【解决方案6】:

      您可以使用 sed 命令并将其作为数组传递给 java sed -i s/0/o/g 文件名

      -i - 更改保存到新文件

      s - 这是用于搜索的

      0 - 要搜索的字符

      o - 要插入的字符

      要检查如何在 Java 中将 sed 用作数组,请查看此链接 How to run sed command from java code

      让我知道这是否适合你

      【讨论】:

      • @slim ..谢谢。明白了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多