如何打印不匹配的字符串

时间:2016-07-06 04:29:09

标签: java

我想打印不匹配的字符串,但结果为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);
  }
}

结果:

  

hello java null //我期待“你好java dddd

我需要放while(!matcher.find())

吗?

3 个答案:

答案 0 :(得分:1)

要实现您想要的效果,您需要检查是否存在替换,如果不存在替换,则需要自行附加密钥

time

希望这会有所帮助。

答案 1 :(得分:1)

以下代码已在IntelliJ 11上测试过,并且似乎正常运行。我认为你的意图是匹配str输入中的每个字符串,如果它在哈希映射中有映射,则可能替换它。问题是你正在进行替换而不实际检查地图中是否出现匹配的单词。我添加了逻辑,如果匹配有映射,则有条件地进行替换。

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);
    }
}

<强>更新

如果您需要担心@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;
}

答案 2 :(得分:1)

如果地图中没有匹配项,mapping.get()将在此代码中返回null

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

我不确定你的期望。看起来你认为如果字符串不在地图中,代码就会神奇地知道你想要跳过appendReplacement。但是,当然,代码无法读懂思想,也无法神奇地工作。如果replacenull,程序仍会继续执行下一行。

您看到的结果是因为+运算符对字符串的作用;如果其中一个操作数为null,则+实际上将四个字符的字符串"null"放入结果中。因此,replace + " ""null ",代码会替换您不匹配的字符串。 (但是,这个:

matcher.appendReplacement(sb, replace);

会给你一个NullPointerException。)

所以基本上,如果没有匹配,你想告诉它不要做替换,并且有几种方法可以做到这一点:

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

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

由于appendReplacement的工作方式,如果您为matcher.find()跳过matcher,则不会触及appendTail附加位置。所以下次循环时,如果匹配,那么前一个匹配(没有映射)将被复制到该点。或者,如果我们退出循环,前一个匹配将被append复制。

但请注意,您编写的代码是在结果中插入额外空格。如果这是您想要的,那么您可能想要修复替换,以便即使没有映射也会增加额外的空间,而不是仅仅在下一个 String replace = mapping.get(matcher.group()); if (replace == null) { replace = matcher.group(); } matcher.appendReplacement(sb, replace + " "); 中复制它。

"ddd"

在您的示例中实际上将"ddd "替换为append。您必须决定如何处理空间。也许你真的不想要额外的空间?请记住,You can check the file uploaded in uploads folder as follows: if(file_exists('path/'.$file_name){ if(move_uploaded_file($tmp_name,$location.$name)){ // file need to be upload in the uploads folder then upload the file into inner folder or may be same folder $thumb_image=$name.'_thumb'; if(copy(source,destination)){ echo 'file uploaded successfully'; // you can delete the file uploaded in the uploads folder as the file is uploaded in the inner folderes } } } 方法会将文本从输入复制到匹配的点,包括那些空格字符。所以你真的不需要包含额外的空格,除非你真的想增加结果中的空格数。