سؤال

أنا أقرأ ملف باستخدام BufferedReader، لذلك دعونا أقول لدي

line = br.readLine();

أريد التحقق مما إذا كان هذا الخط يحتوي على واحدة من العديد من الأوتار الممكنة (التي لدي في صفيف). أود أن أكون قادرا على كتابة شيء مثل:

while (!line.matches(stringArray) { // not sure how to write this conditional
  do something here;
  br.readLine();
}

أنا جديد إلى حد ما في البرمجة وجافا، هل سأذهب في هذه الطريقة الصحيحة؟

هل كانت مفيدة؟

المحلول

نسخ جميع القيم في Set<String> ثم استخدم contains():

Set<String> set = new HashSet<String> (Arrays.asList (stringArray));
while (!set.contains(line)) { ... }

عدل] إذا كنت ترغب في معرفة ما إذا جزء من الخط يحتوي على سلسلة من المجموعة، يجب عليك حلقة على المجموعة. يحل محل set.contains(line) مع مكالمة إلى:

public boolean matches(Set<String> set, String line) {
    for (String check: set) {
        if (line.contains(check)) return true;
    }
    return false;
}

اضبط الشيك وفقا عند استخدام RegexP أو طريقة أكثر تعقيدا للمطابقة.

edit2] خيار ثالث هو الحصول على العناصر في الصفيف في RegexP ضخمة مع |:

Pattern p = Pattern.compile("str1|str2|str3");

while (!p.matcher(line).find()) { // or matches for a whole-string match
    ...
}

يمكن أن يكون هذا أكثر ريحة إذا كان لديك العديد من العناصر في الصفيف لأن رمز Regexp سيؤدي إلى تحسين عملية المطابقة.

نصائح أخرى

يعتمد على ماذا stringArray هو. إذا كان Collection ثم غرامة. إذا كانت مجموعة حقيقية، يجب أن تجعلها Collection. وبعد ال Collection واجهة لديها طريقة تسمى contains() من شأنها تحديد ما إذا كانت معينة Object في ال Collection.

طريقة بسيطة لتحويل صفيف إلى Collection:

String tokens[] = { ... }
List<String> list = Arrays.asList(tokens);

المشكلة مع List هل هذه البحث باهظ الثمن (خطي تقنيا أو O(n)). رهان أفضل هو استخدام Set, ، الذي لا يسرد ولكنه ثابت (O(1)) ابحث عن. يمكنك بناء واحد مثل هذا:

من Collection:

Set<String> set = new HashSet<String>(stringList);

من صفيف:

Set<String> set = new HashSet<String>(Arrays.asList(stringArray));

وثم set.contains(line) ستكون عملية رخيصة.

تعديل: حسنا، أعتقد أن سؤالك لم يكن واضحا. تريد معرفة ما إذا كان الخط يحتوي على أي من الكلمات في الصفيف. ما تريد ثم شيء مثل هذا:

BufferedReader in = null;
Set<String> words = ... // construct this as per above
try {
  in = ...
  while ((String line = in.readLine()) != null) {
    for (String word : words) {
      if (line.contains(word)) [
        // do whatever
      }
    }
  }
} catch (Exception e) {
  e.printStackTrace();
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
}

هذا هو الشيكات الخام تماما، والذي يستخدم مفتوحا بشكل مدهش ويميل إلى إعطاء إيجابيات مزعجة مزعجة على الكلمات مثل "الخردة". للحصول على حل أكثر تطورا، ربما عليك استخدام تعبير منتظم وابحث عن حدود الكلمات:

Pattern p = Pattern.compile("(?<=\\b)" + word + "(?=\b)");
Matcher m = p.matcher(line);
if (m.find() {
  // word found
}

ربما تريد أن تفعل هذا أكثر كفاءة (مثل عدم تجميع النمط مع كل سطر) ولكن هذه هي الأداة الأساسية لاستخدامها.

باستخدام String.matches(regex) وظيفة، ماذا عن إنشاء تعبير منتظم يطابق أي واحد من السلاسل في صفيف السلسلة؟ شيء مثل

String regex = "*(";
for(int i; i < array.length-1; ++i)
  regex += array[i] + "|";
regex += array[array.length] + ")*";
while( line.matches(regex) )
{
  //. . . 
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top