2010-07-27 2 views
1

Как я могу найти разные символы в строках на одинаковых позициях? Пример:Найти разные символы в двух строках

String string1 = "Anand has 2 bags and 4 apples"; 
String n = /* ??? */; 
String n2 = /* ??? */; 
String string2 = "Anand has " + n + " bags and " + n2 + " apples"; 

Я хочу n = "2" и n1 = "4".

Пожалуйста, дайте мне знать, как мы можем это сделать? (Пространство добавлено между словами только для ясности, но я не могу использовать пробел как разделитель)

+2

Отредактировано для уточнения вопроса, насколько я мог это понять. Я мог бы быть совершенно не знаком ... –

+1

@Bears ... хорошее редактирование. Было бы неплохо увидеть, что вишну вернется, чтобы рассказать нам, действительно ли это то, что он имел в виду или нет. btw ... сколько rep. нужно ли уметь редактировать? – Hristo

+0

Я не понял почему вы разместили следующий код String n =/* ??? * /; Строка n2 =/* ??? */;. Если вы не возражаете, пожалуйста, объясните им – vishnu

ответ

0

Вы можете использовать класс StringTemplate, что я разработал (я разработал класс URITemplate, чтобы соответствовать restlike URIs но изменил его использовать строки, а)

// Licensed Apache2 (http://www.apache.org/licenses/LICENSE-2.0.txt) 
    import java.util.List; 

    import java.net.URL; 
    import java.net.URLConnection; 

    import java.util.Map; 
    import java.util.ArrayList; 
    import java.util.LinkedHashMap; 
    import java.util.regex.Matcher; 
    import java.util.regex.Pattern; 

    /** 
    * <pre> 
    * StringTemplate t = new StringTemplate("/catalog/{categoryId}/products/{productId}/summary"); 
    * t.matches("/catalog/23/products/12375/summary"); // returns true 
    * t.match("/catalog/23/products/12375/summary"); // returns a map {categoryId=23, productId=12375} 
    * </pre> 
    * 
    * @author anaik 
    */ 
    public class StringTemplate { 
    /** The meta pattern for template to match sequence such as: {someVar} */ 
    private static final Pattern patternPattern = Pattern.compile("\\{([^\\{\\}]+)\\}"); 
    /** The pattern string */ 
    private String stringPattern; 
    /** The generated pattern when the stringPattern is parsed */ 
    private Pattern thisStringPattern; 
    /** Variable names found in this pattern in that order */ 
    private List<String> vars = new ArrayList<String>(); 

    /** 
     * Creates a new StringTemplate from the specified pattern 
     * @param Pattern 
     */ 
    private StringTemplate(String stringPattern) { 
     this.stringPattern = stringPattern; 
     initialize(); 
    } 

    /** 
     * Gets the names of variables - those defined in {variable-name} constructs - in this StringTemplate 
     * in the order they were specified 
     * @return a list of variables or an empty list if no variables were found 
     */ 
    public List<String> getVars() { 
     return vars; 
    } 

    /** 
     * Determine whether the specified <tt>actualString</code> matches with this StringTemplate 
     * @param actualString The actual to match 
     * @return true iff successfull match 
     */ 
    public boolean matches(String actualString) { 
     return thisStringPattern.matcher(actualString).matches(); 
    } 

    /** 
     * Matches the <tt>actualString</tt> with this StringTemplate and extracts values for all the variables 
     * in this template and returns them as an ordered map (keys defined in the same order as that of 
     * the StringTemplate. If the match was unsuccessfull, an empty map is returned. Note that this method 
     * should be ideally be called after {@link #matches(java.lang.String) } to check whether the 
     * specified actually matches the template 
     */ 
    public Map<String, String> match(String actualString) { 
     Matcher m = thisStringPattern.matcher(actualString); 
     Map<String, String> map = new LinkedHashMap<String, String>(); 
     if(m.matches()) { 
      int gc = m.groupCount(); 
      for(int i = 0; i < gc; i++) { 
       int g = i + 1; 
       map.put(vars.get(i), actualString.substring(m.start(g), m.end(g))); 
      } 
     } 
     return map; 
    } 

    private void initialize() { 
     Matcher m = patternPattern.matcher(stringPattern); 
     StringBuffer builder = new StringBuffer(); 

     while(m.find()) { 
      String var = m.group(1); 
      vars.add(var); 
      m.appendReplacement(builder, "(.*)"); 
     } 
     m.appendTail(builder); 
     String genPattern = builder.toString(); 
     thisStringPattern = Pattern.compile(genPattern); 
    } 

    public static void main(String[] args) throws Throwable { 
     StringTemplate t = new StringTemplate(args[0]); 
     System.out.println("Matches with actual Class Identifier: java.lang.String: " + t.matches(args[1])); 
     System.out.println("Var values: " + t.match(args[1])); 
    } 
    } 

Компиляцию это и тест следующим образом:

tmp$ java StringTemplate "Anand has {n} bags and {n1} apples" "Anand has 23 bags and 500 apples" 

Это выход

Matches with actual URI: true 
Var values: {n=23, n1=500} 

спички (String) возвращает карту, содержащие имена переменных шаблона и значение. Этот класс может использоваться для сопоставления любой строки с любым количеством варов. Его liscensed apache2

Если входная строка содержит регулярное выражение символов, вы должны избавиться от них:

input = input.replaceAll("\\$", "\\\\\\$"); 
    input = input.replaceAll("\\(", "\\\\("); 
    input = input.replaceAll("\\)", "\\\\)"); 
    StringTemplate st = new StringTemplate(input); 

Обратите внимание, что вам нужно более точные регэкспы для условий, когда входная строка уже есть символы, такие как «\ $»

+0

Большое спасибо. Я рассматриваю этот тип сравнения. Потому что пространство добавлено только для ясности. Но это не подходит ни к какому-то специальному каракуле. Верный? Есть ли способ изменить регулярное выражение для соответствия любому символу или специальному символу. Значит, он должен соответствовать: $ E (VAL, 1,2) __ $ E (VAL, 3,5) – vishnu

+0

@vishnu, я пробовал это с: java StringTemplate «Ананд имеет {n} сумки и {n1} яблоки «« Ананд имеет 23 мешка и 3 доллара США (VAL, 1,2) __ $ E (VAL, 3,5) « и получил выход: Значения варны: {n = 3, n1 = VAL, 1, 2) __ (VAL, 3,5)} – naikus

+0

Я пробовал $ E (VAL, {i1}, {i2}) __ $ E (VAL, {i4}, {i5}) с $ E (VAL, 1,2) __ $ E (VAL, 3,5), но я получил сообщение: Соответствует фактическому идентификатору класса: java.lang.String: false Значения Var: {}. У моего шаблона есть все разные символы, включая двойные кавычки (пробелы), пробелы, двоеточие, минус и т. Д. ... поэтому, пожалуйста, предложите мне регулярное выражение, соответствующее любому – vishnu

0

Регулярное выражение должно делать это красиво.

+2

Уход за разработкой? – BalusC

+4

Обязательно «Некоторые люди, столкнувшись с проблемой, думают « Я знаю, я буду использовать регулярные выражения ». Теперь у них две проблемы». – whaley

+0

@whaley ...: D hahaha. Это напоминает мне о профессоре моего класса Computer Architecture. Его менталитет состоял в том, что «все можно сделать с помощью XOR» :) – Hristo

1

Вы могли бы использовать для петли к петле по длине меньшего из строк и проверки на каждой позиции в отдельности

0

Если длины не то же самое:

for(int i = 0; i < Math.min(str1.length, str2.length); i++){ 
    if(str1.charAt(i) != str2.charAt(i)){ 
     //Different 
    } 
} 

for(int i = Math.min(str1.length, str2.length); 
      i < Math.max(str1.length, str2.length); i++){ 
    //Each is in one but not the other. 
} 

Если длины один и те же:

for(int i = 0; i < str1.length; i++){ 
    if(str1.charAt(i) != str2.charAt(i)){ 
     //Different 
    } 
} 
0

Я бы разделил Струны на «пространства», то я сделал бы цикл ищет числа в результирующем массиве. Вот небольшой пример, это clumpsy, но он получает работу:

import java.util.ArrayList; 

public class XXX{ 
    public static void main(String[] args){ 
     String str = "Anand has 2 bags and 4 apples"; 

     System.out.println("Start..."); 
     System.out.println(str); 
     String words[] = str.split("\\s+"); 

     ArrayList<String> values = new ArrayList<String>(); 

     for(String s:words){ 
      System.out.println(s); 
      try{ 
       Integer.parseInt(s); 
       values.add(s); 
      } 
      catch(NumberFormatException ex){ 
       System.out.println(s + " is not a number"); 
      }  
     } 

     System.out.println("Anand has " + values.get(0) + " bags and " + values.get(1) + " apples"); 

    } 
} 
1

Если вы уверены в своем тексте в строке остается тем же вы можете сделать что-то вроде этого -

String string1 ="Anand has 2 bags and 4 apples"; 
String[] parts = string1.split("\\s+"); 
System.out.println("n = " + parts[2] + " n1 = " + parts [5]); 
Смежные вопросы