[java] كيفية تقسيم سلسلة في جاوة



14 Answers

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

import java.util.regex.Pattern;
import java.util.regex.Matcher;

class SplitExample
{
    private static Pattern twopart = Pattern.compile("(\\d+)-(\\d+)");

    public static void checkString(String s)
    {
        Matcher m = twopart.matcher(s);
        if (m.matches()) {
            System.out.println(s + " matches; first part is " + m.group(1) +
                               ", second part is " + m.group(2) + ".");
        } else {
            System.out.println(s + " does not match.");
        }
    }

    public static void main(String[] args) {
        checkString("123-4567");
        checkString("foo-bar");
        checkString("123-");
        checkString("-4567");
        checkString("123-4567-890");
    }
}

بما أن النسق ثابت في هذه الحالة ، يمكن تجميعه مسبقًا وتخزينه كعضو ثابت (يتم البدء به في وقت تحميل الفصل في المثال). التعبير العادي هو:

(\d+)-(\d+)

تشير الأقواس إلى مجموعات الالتقاط؛ يمكن الوصول إلى السلسلة التي تطابق هذا الجزء من regexp بواسطة الأسلوب Match.group () ، كما هو موضح. تشير المطابقات \ d والأرقام العشرية الفردية ، و + إلى "تطابق واحد أو أكثر من التعبير السابق." - ليس له معنى خاص ، لذلك فقط يطابق هذا الحرف في الإدخال. لاحظ أنك تحتاج إلى إزاحة مزدوجة عن الخطوط المائلة العكسية عند كتابة هذا كسلسلة Java ، بعض الأمثلة الأخرى:

([A-Z]+)-([A-Z]+)          // Each part consists of only capital letters 
([^-]+)-([^-]+)            // Each part consists of characters other than -
([A-Z]{2})-(\d+)           // The first part is exactly two capital letters,
                           // the second consists of digits
Question

لدي سلسلة "004-034556" ، التي أريد تقسيمها إلى سلسلتين:

string1=004
string2=034556

وهذا يعني أن السلسلة الأولى سوف تحتوي على الأحرف قبل '-' ، وستحتوي السلسلة الثانية على الأحرف بعد '-' . أرغب أيضًا في التحقق مما إذا كانت السلسلة تحتوي على '-' في ذلك. إذا لم يكن كذلك ، سوف أرمي استثناء. كيف يمكنني أن أفعل هذا؟




للتلخيص: هناك خمس طرق على الأقل لتقسيم سلسلة في جافا:

  1. String.split ():

    String[] parts ="10,20".split(",");
    
  2. Pattern.compile (التعبير العادي) .splitAsStream (المدخلات):

    List<String> strings = Pattern.compile("\\|")
          .splitAsStream("010|020202")
          .collect(Collectors.toList());
    
  3. StringTokenizer (فئة قديمة):

    StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", ".");
    while(strings.hasMoreTokens()){
        String substring = strings.nextToken();
        System.out.println(substring);
    }
    
  4. Google Guava Splitter:

    Iterable<String> result = Splitter.on(",").split("1,2,3,4");
    
  5. Apache Commons StringUtils:

    String[] strings = StringUtils.split("1,2,3,4", ",");
    

لذا يمكنك اختيار الخيار الأفضل لك بناءً على ما تحتاج إليه ، على سبيل المثال ، نوع الإرجاع (المصفوفة ، القائمة ، أو التكرار).

Here نظرة عامة كبيرة على هذه الأساليب والأمثلة الأكثر شيوعًا (كيفية التقسيم حسب النقطة ، والشرطة المائلة ، وعلامة الاستفهام ، وما إلى ذلك)




متطلبات تركت مجالا للتفسير. أوصي بكتابة طريقة ،

public final static String[] mySplit(final String s)

الذي يغلف هذه الوظيفة. بالطبع يمكنك استخدام String.split (..) كما ذكر في الإجابات الأخرى للتنفيذ.

يجب أن تكتب بعض اختبارات الوحدة لسلسلة الإدخال والنتائج والسلوك المرغوب.

يجب أن يشمل المتقدمون للاختبار الجيد ما يلي:

 - "0022-3333"
 - "-"
 - "5555-"
 - "-333"
 - "3344-"
 - "--"
 - ""
 - "553535"
 - "333-333-33"
 - "222--222"
 - "222--"
 - "--4555"

مع تحديد نتائج الاختبار ، يمكنك تحديد السلوك.

على سبيل المثال ، إذا كان "-333" يجب أن يرجع في [,333] أو إذا كان خطأ. هل يمكن "333-333-33" في [333,333-33] or [333-333,33] أو هل هو خطأ؟ وما إلى ذلك وهلم جرا.




الرجاء عدم استخدام فئة StringTokenizer حيث إنها فئة قديمة يتم الاحتفاظ بها لأسباب التوافق ، ويتم تثبيط استخدامها في التعليمات البرمجية الجديدة. ويمكننا استخدام أسلوب الانقسام كما اقترحه الآخرون أيضًا.

String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));

وكما هو متوقع ، ستتم طباعة:

[004, 034556]

في هذه الإجابة ، أود أيضًا الإشارة إلى تغيير واحد تم split لطريقة split في Java 8 . أسلوب String#split() يجعل استخدام Pattern.split ، والآن سيزيل السلاسل الفارغة في بداية مصفوفة النتائج. لاحظ هذا change في وثائق Java 8:

عند وجود تطابق عرض موجب في بداية تسلسل الإدخال ، يتم تضمين سلسلة فرعية فارغة فارغة في بداية الصفيف الناتج. ومع ذلك ، لا ينتج عن المطابقة ذات العرض الصفري في البداية مطلقًا سلسلة فرعية فارغة.

هذا يعني بالنسبة للمثال التالي:

String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));

سنحصل على ثلاث سلاسل: [0, 0, 4] وليس أربعة كما كان الحال في Java 7 وما قبله. تحقق أيضا من هذا question مماثل.




فيما يلي طريقتان تحققهما.

طريقة 1: عندما تضطر إلى تقسيم رقمين بحرف خاص ، يمكنك استخدام تعبير عادي

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TrialClass
{
    public static void main(String[] args)
    {
        Pattern p = Pattern.compile("[0-9]+");
        Matcher m = p.matcher("004-034556");

        while(m.find())
        {
            System.out.println(m.group());
        }
    }
}

الطريقة الثانية: استخدام طريقة تقسيم السلسلة

public class TrialClass
{
    public static void main(String[] args)
    {
        String temp = "004-034556";
        String [] arrString = temp.split("-");
        for(String splitString:arrString)
        {
            System.out.println(splitString);
        }
    }
}



لتقسيم سلسلة ، استخدم String.split(regex) :

String phone = "004-034556";
String[] output = phone.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

انتاج:

004
034556






يمكنك أن تجرب مثل هذا أيضا

 String concatenated_String="hi^Hello";

 String split_string_array[]=concatenated_String.split("\\^");



 String string = "004^034556-34";
 String[] parts = string.split(Pattern.quote("^"));

إذا كان لديك شخصية خاصة ، يمكنك استخدام Patter.quote. إذا كان لديك شرطة بسيطة (-) ، فيمكنك حينئذ تقصير الشفرة:

 String string = "004-34";
 String[] parts = string.split("-");

إذا حاولت إضافة حرف خاص آخر بدلاً من الشرطة (^) ، فسيؤدي الخطأ إلى إنشاء ArrayIndexOutOfBoundsException . لذلك عليك استخدام Pattern.quote .




مع Java 8:

    List<String> stringList = Pattern.compile("-")
            .splitAsStream("004-034556")
            .collect(Collectors.toList());

    stringList.forEach(s -> System.out.println(s));



الطريقة الأسرع ، التي تستهلك أيضًا أقل الموارد هي:

String s = "abc-def";
int p = s.indexOf('-');
if (p >= 0) {
    String left = s.substring(0, p);
    String right = s.substring(p + 1);
} else {
  // s does not contain '-'
}



يمكنك تقسيم سلسلة بفاصل سطر باستخدام العبارة التالية:

String textStr[] = yourString.split("\\r?\\n");

يمكنك تقسيم سلسلة باستخدام واصلة / حرف باستخدام العبارة التالية:

String textStr[] = yourString.split("-");



من الوثائق:

public String[] split(String regex,int limit) هذه السلسلة حول التطابقات الخاصة بالتعبير العادي المحدد . يحتوي المصفوفة التي تم إرجاعها بواسطة هذا الأسلوب على كل سلسلة فرعية من هذه السلسلة التي تم إنهاؤها بواسطة سلسلة فرعية أخرى تتطابق مع التعبير الموضح أو تم إنهاؤها بنهاية السلسلة. تكون سلاسل فرعية في الصفيف بالترتيب الذي تحدث به في هذه السلسلة. إذا كان التعبير لا يتطابق مع أي جزء من الإدخال ، فإن الصفيف الناتج يحتوي على عنصر واحد فقط ، أي هذه السلسلة.

أساسا يمكنك القيام بشيء كالتالي:

String s = "123-456-789-123"; // The String to be split
String[] array = s.split("-"); // Split according to the hyphen and put them in an array
for(String subString : array){ // Cycle through the array
   System.out.println(subString);
}

انتاج:

123
456
789
123



// This leaves the regexes issue out of question
// But we must remember that each character in the Delimiter String is treated
// like a single delimiter        

public static String[] SplitUsingTokenizer(String subject, String delimiters) {
   StringTokenizer strTkn = new StringTokenizer(subject, delimiters);
   ArrayList<String> arrLis = new ArrayList<String>(subject.length());

   while(strTkn.hasMoreTokens())
      arrLis.add(strTkn.nextToken());

   return arrLis.toArray(new String[0]);
}



لحالات الاستخدام البسيط ، يجب أن تقوم String#split() بهذه المهمة. إذا كنت تستخدم الجوافة ، فهناك أيضًا فئة Splitter تسمح بتسلسل عمليات سلسلة مختلفة ويدعم CharMatcher :

Splitter.on('-')
       .trimResults()
       .omitEmptyStrings()
       .split(string);





Related



Tags

java java   string