java الوسطى - كيفية تقسيم سلسلة في جاوة




الشرقية منطقه (25)

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

string1=004
string2=034556

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


Answers

String s="004-034556";
for(int i=0;i<s.length();i++)
{
    if(s.charAt(i)=='-')
    {
        System.out.println(s.substring(0,i));
        System.out.println(s.substring(i+1));
    }
}

كما ذكر الجميع ، فإن split () هو أفضل خيار يمكن استخدامه في حالتك. يمكن استخدام أسلوب بديل باستخدام السلسلة الفرعية ().


لتقسيم سلسلة ، يستخدم String.split (regex). راجع الأمثلة التالية:

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

انتاج |

004
034556

ملاحظة هذا الانقسام (regex) يأخذ تعبيرًا عاديًا كوسيطة ، تذكر أن تتفادى أحرف خاصة regex ، مثل النقطة / النقطة.


إحدى الطرق للقيام بذلك هي تشغيل السلسلة في حلقة for-each واستخدام الحرف الانقسام المطلوب.

public class StringSplitTest {

    public static void main(String[] arg){
        String str = "004-034556";
        String split[] = str.split("-");
        System.out.println("The split parts of the String are");
        for(String s:split)
        System.out.println(s);
    }
}

انتاج:

The split parts of the String are:
004
034556

String[] out = string.split("-");

يجب أن تفعل الشيء الذي تريده. تحتوي فئة السلسلة على العديد من الطرق للعمل بالسلسلة.


يمكنك استخدام Split ():

import java.io.*;

public class Splitting
{

    public static void main(String args[])
    {
        String Str = new String("004-034556");
        String[] SplittoArray = Str.split("-");
        String string1 = SplittoArray[0];
        String string2 = SplittoArray[1];
    }
}

آخر ، يمكنك استخدام StringTokenizer:

import java.util.*;
public class Splitting
{
    public static void main(String[] args)
    {
        StringTokenizer Str = new StringTokenizer("004-034556");
        String string1 = Str.nextToken("-");
        String string2 = Str.nextToken("-");
    }
}

public class SplitTest {

    public static String[] split(String text, String delimiter) {
        java.util.List<String> parts = new java.util.ArrayList<String>();

        text += delimiter;

        for (int i = text.indexOf(delimiter), j=0; i != -1;) {
            String temp = text.substring(j,i);
            if(temp.trim().length() != 0) {
                parts.add(temp);
            }
            j = i + delimiter.length();
            i = text.indexOf(delimiter,j);
        }

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


    public static void main(String[] args) {
        String str = "004-034556";
        String delimiter = "-";
        String result[] = split(str, delimiter);
        for(String s:result)
            System.out.println(s);
    }
}

String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter

string1=004 // sTemp[0];
string2=034556//sTemp[1];

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

  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 نظرة عامة كبيرة على هذه الأساليب والأمثلة الأكثر شيوعًا (كيفية التقسيم حسب النقطة ، والشرطة المائلة ، وعلامة الاستفهام ، وما إلى ذلك)


استخدم طريقة الانقسام org.apache.commons.lang.StringUtils' التي يمكنها تقسيم السلاسل استنادًا إلى الحرف أو السلسلة التي تريد تقسيمها.

توقيع الطريقة:

public static String[] split(String str, char separatorChar);

في حالتك ، تريد تقسيم سلسلة عندما يكون هناك "-".

يمكنك ببساطة القيام بما يلي:

String str = "004-034556";

String split[] = StringUtils.split(str,"-");

انتاج:

004
034556

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


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

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

تقسيم السلسلة مع عدة أحرف باستخدام Regex

public class StringSplitTest {
     public static void main(String args[]) {
        String s = " ;String; String; String; String, String; String;;String;String; String; String; ;String;String;String;String";
        //String[] strs = s.split("[,\\s\\;]");
        String[] strs = s.split("[,\\;]");
        System.out.println("Substrings length:"+strs.length);
        for (int i=0; i < strs.length; i++) {
            System.out.println("Str["+i+"]:"+strs[i]);
        }
     }
  }

انتاج:

Substrings length:17
Str[0]:
Str[1]:String
Str[2]: String
Str[3]: String
Str[4]: String
Str[5]: String
Str[6]: String
Str[7]:
Str[8]:String
Str[9]:String
Str[10]: String
Str[11]: String
Str[12]:
Str[13]:String
Str[14]:String
Str[15]:String
Str[16]:String

ولكن لا تتوقع نفس الإخراج عبر جميع إصدارات JDK. لقد رأيت خطأ واحد موجود في بعض إصدارات JDK حيث تم تجاهل أول سلسلة فارغة. هذا الخطأ غير موجود في أحدث إصدار JDK ، ولكنه موجود في بعض الإصدارات بين الإصدارات المتأخرة JDK 1.7 والإصدارات 1.8 الأولى.


يمكنك ببساطة استخدام StringTokenizer لتقسيم سلسلة في جزأين أو أكثر سواء كان هناك أي نوع من المحددات:

StringTokenizer st = new StringTokenizer("004-034556", "-");
while(st.hasMoreTokens())
{
    System.out.println(st.nextToken());
}

import java.io.*;

public class BreakString {

  public static void main(String args[]) {

    String string = "004-034556-1234-2341";
    String[] parts = string.split("-");

    for(int i=0;i<parts.length;i++) {
      System.out.println(parts[i]);
    }
  }
}

أردت فقط كتابة خوارزمية بدلاً من استخدام وظائف Java المضمنة:

public static List<String> split(String str, char c){
    List<String> list = new ArrayList<>();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < str.length(); i++){
        if(str.charAt(i) != c){
            sb.append(str.charAt(i));
        }
        else{
            if(sb.length() > 0){
                list.add(sb.toString());
                sb = new StringBuilder();
            }
        }
    }

    if(sb.length() >0){
        list.add(sb.toString());
    }
    return list;
}


مع 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 '-'
}

افترض أن

  • لا تحتاج بالفعل إلى تعبيرات عادية لتقسيمك
  • كنت تستخدم بالفعل أباتشي أباتشي لانج في التطبيق الخاص بك

أسهل طريقة هي استخدام StringUtils # split (java.lang.String، char) . هذا أكثر ملاءمة من الذي توفره Java من خارج منطقة الجزاء إذا لم تكن بحاجة إلى تعبيرات عادية. وكما يقول دليلها ، فإنها تعمل على النحو التالي:

A null input String returns null.

 StringUtils.split(null, *)         = null
 StringUtils.split("", *)           = []
 StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
 StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
 StringUtils.split("a:b:c", '.')    = ["a:b:c"]
 StringUtils.split("a b c", ' ')    = ["a", "b", "c"]

أوصي باستخدام commong-lang ، لأنه عادة ما يحتوي على الكثير من الأشياء التي يمكن استخدامها. ومع ذلك ، إذا لم تكن بحاجة إلى أي شيء آخر غير القيام بعملية انقسام ، فإن تنفيذ نفسك أو الهروب من regex يعد خيارًا أفضل.


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

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

انتاج:

004
034556

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

طريقة 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);
        }
    }
}

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

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] أو هل هو خطأ؟ وما إلى ذلك وهلم جرا.


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

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

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

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

الرجاء عدم استخدام فئة 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 مماثل.


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

ستكون الإجابة القصيرة والمباشرة لأنها char[]قابلة للتغيير بينما Stringلا تكون الكائنات.

Stringsفي جاوة هي كائنات غير قابلة للتغيير. لهذا السبب لا يمكن تعديلها بمجرد إنشائها ، وبالتالي فإن الطريقة الوحيدة لإزالة محتوياتها من الذاكرة هي جمعها. سيكون عندئذ فقط عندما يمكن الكتابة فوق الذاكرة المحررة بواسطة الكائن ، وستزول البيانات.

الآن لا يحدث تجميع البيانات المهملة في Java في أي فترة مضمونة. و Stringبالتالي يمكن أن تستمر في الذاكرة لفترة طويلة، وإذا تعطل عملية خلال هذا الوقت، ومحتويات السلسلة قد ينتهي في تفريغ الذاكرة أو بعض السجل.

باستخدام صفيف الحروف ، يمكنك قراءة كلمة المرور ، والانتهاء من العمل بها في أقرب وقت ممكن ، ثم تغيير المحتويات على الفور.







java string