简体   繁体   English

如何打印不匹配的字符串

[英]How to print not match string

I would like to print not matching string but the result null. 我想打印不匹配的字符串,但结果为null。

public class Replacement  {
   public static void main(String[] ignored)  {

      String str = "aaa bbb ddd";
      Map<String, String> mapping = new HashMap<>();
      mapping.put("aaa", "hello");
      mapping.put("bbb", "java");
      mapping.put("ccc", "world");

      Pattern pattern = Pattern.compile("([a-zA-Z_]+)"); // pattern compiling
      Matcher matcher = pattern.matcher(str); // pattern matching

      StringBuffer sb = new StringBuffer();
      while(matcher.find())  { // while matcher found
         String replace = mapping.get(matcher.group());
         matcher.appendReplacement(sb, replace + " ");
      }
      matcher.appendTail(sb);

      System.out.println(sb);
  }
}

The result: 结果:

hello java null // I expected "hello java dddd hello java null //我期待“你好java dddd

Do I need to put while(!matcher.find()) 我需要把while(!matcher.find())

To achieve what you want, you need to check whether a replacement exists or not, if replacement does not exist then you need to append the key itself 为了达到你想要的效果,你需要检查是否存在替换,如果不存在替换,那么你需要附加密钥本身

     String replace = mapping.get(matcher.group());
     if(replace==null) {
         replace = matcher.group();
     }
     matcher.appendReplacement(sb, replace + " ");

hope this helps. 希望这可以帮助。

The following code has been tested on IntelliJ 11 and appears to be working correctly. 以下代码已在IntelliJ 11上进行了测试,似乎工作正常。 I think your intention is to match each string in the str input, and potentially replace it, if it has a mapping in the hash map. 我认为你的意图是匹配str输入中的每个字符串,如果它在哈希映射中有映射,则可能替换它。 The problem is that you are doing a replace without actually checking if a matched word appears in the map. 问题是你正在进行替换而不实际检查地图中是否出现匹配的单词。 I added logic that conditionally makes a replacement iff a match has a mapping. 我添加了逻辑,如果匹配有映射,则有条件地进行替换。

public class Replacement  {
    public static void main(String[] ignored)  {

        String str = "aaa bbb ddd";
        Map<String, String> mapping = new HashMap<String, String>();
        mapping.put("aaa", "hello");
        mapping.put("bbb", "java");
        mapping.put("ccc", "world");

        Pattern pattern = Pattern.compile("([a-zA-Z_]+)");compiling
        Matcher matcher = pattern.matcher(str);

        StringBuffer sb = new StringBuffer();
        while(matcher.find())  {
            String key = matcher.group();       // matched word is key into the map
            String value = mapping.get(key);    // attempt to get mapped word
            if (value != null) {                // if mapping exists,
                str = str.replace(key, value);  //   then make replacement
            }
        }
        System.out.println(str);
    }
}

Update: 更新:

If you need to worry about edge cases along the lines of what @ajb pointed out, it would be safer to just split your original string by space, selectively replace each word, and then roll it back up into a single string again: 如果您需要担心@ajb所指出的边缘情况,那么用空格分割原始字符串会更安全,选择性地替换每个单词,然后再将其重新卷回一个字符串:

String[] parts = str.split(" ");
String output = "";

for (int i=0; i < parts.length; ++i) {
    String value = mapping.get(parts[i]);
    if (value == null) {
        value = parts[i];
    }

    if (i > 0) {
        output += " ";
    }
    output += value;
}

If there is no match in the map, mapping.get() would return null in this code: 如果映射中没有匹配项,则mapping.get()将在此代码中返回null

     String replace = mapping.get(matcher.group());
     matcher.appendReplacement(sb, replace + " ");

I'm not sure what you expected. 我不确定你的期望。 It seems like you thought that if the string wasn't in the map, the code would magically know that you would want to skip the appendReplacement . 看起来你认为如果字符串不在地图中,代码就会神奇地知道你想要跳过appendReplacement But, of course, code can't read minds and doesn't work magically. 但是,当然,代码无法读懂思想,也无法神奇地工作。 If replace is null , the program would still go ahead and try to execute the next line. 如果replacenull ,程序仍将继续并尝试执行下一行。

The result you're seeing is because of how the + operator works on strings; 你看到的结果是因为+运算符如何处理字符串; if one of the operands is null , then + actually puts the four-character string "null" into the result. 如果其中一个操作数为null ,则+实际上将四个字符的字符串"null"放入结果中。 Thus, replace + " " is "null " , and the code replaces your unmatched string with that. 因此, replace + " ""null " ,代码将替换您不匹配的字符串。 (However, this: (但是,这个:

matcher.appendReplacement(sb, replace);

would have given you a NullPointerException.) 会给你一个NullPointerException。)

So basically, you want to tell it not to do the replacement if there's no match, and there are a couple ways to do this: 所以基本上,如果没有匹配,你想告诉它不要做替换,并且有几种方法可以做到这一点:

 String replace = mapping.get(matcher.group());
 if (replace != null) {
     matcher.appendReplacement(sb, replace + " ");
 }

or 要么

if (mapping.containsKey(matcher.group())) {
    String replace = mapping.get(matcher.group());
    matcher.appendReplacement(sb, replace + " ");
}

Because of the way appendReplacement works, if you skip it for one matcher.find() , it doesn't touch matcher 's append position . 由于appendReplacement工作方式,如果你跳过一个matcher.find() ,它不会触及matcher追加位置 So the next time through the loop, if there is a match, the previous match (that didn't have a mapping) would get copied in at that point. 所以下次循环时,如果匹配,那么前一个匹配(没有映射)将被复制到该点。 Or, if we fall out of the loop, the previous match would get copied by appendTail . 或者,如果我们退出循环,前一个匹配将被appendTail复制。

But note that the code you wrote is inserting extra spaces into the result. 但请注意,您编写的代码是在结果中插入额外的空格。 If that's what you want, then you might want to fix the replacement so that it adds an extra space even if there's no mapping, instead of just copying it in the next append . 如果这就是你想要的,那么你可能想要修复替换,以便即使没有映射也会增加额外的空间,而不是仅仅在下一个append复制它。

 String replace = mapping.get(matcher.group());
 if (replace == null) {
     replace = matcher.group();
 }
 matcher.appendReplacement(sb, replace + " ");

which would in effect replace "ddd" by "ddd " in your example. 这实际上将取代"ddd""ddd "在你的例子。 You'll have to decide how you want to handle the spaces. 您必须决定如何处理空间。 Maybe you really didn't want extra spaces? 也许你真的不想要额外的空间? Remember that the append methods will copy text from the input up to the point that matched, including those space characters. 请记住, append方法会将文本从输入复制到匹配的点,包括那些空格字符。 So you really don't need to include an extra space, unless you really want to increase the number of spaces in the result. 所以你真的不需要包含额外的空间,除非你真的想增加结果中的空格数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM