لدي سلسلة ، "004-034556"
، أريد تقسيمها إلى سلسلتين:
string1="004";
string2="034556";
هذا يعني أن السلسلة الأولى ستحتوي على الأحرف قبل '-'
، وستحتوي السلسلة الثانية على الأحرف بعد '-'
. أريد أيضًا التحقق مما إذا كانت السلسلة تحتوي على '-'
. إذا لم يكن كذلك ، سوف رمي استثناء. كيف يمكنني أن أفعل هذا؟
فقط استخدم الطريقة المناسبة: String#split()
.
String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556
لاحظ أن هذا يتطلب تعبيرًا منتظمًا ، لذلك تذكر الهروب أحرف خاصة إذا لزم الأمر.
هناك 12 حرفًا معانٍ خاصة: الخط المائل العكسي
\
، علامة الإقحام^
، علامة الدولار$
، الفترة أو النقطة.
، الشريط العمودي أو رمز توجيه الإخراج|
، علامة الاستفهام?
، علامة الاستفهام*
، علامة النجمة علامة الجمع+
، وأقواس الفتح(
، وأقواس الإغلاق)
، وقوس مربع الفتح[
، ومحمول الفتح المجعد{
، وغالبًا ما تسمى هذه الأحرف الخاصة "metacharacters".
لذا ، إذا كنت تريد الانفصال على سبيل المثال الفترة/النقطة .
التي تعني " أي حرف " في regex ، استخدم إما الخط المائل العكسي \
للهروب من الشخصية الخاصة الفردية مثل split("\\.")
، أو استخدام فئة الحرف []
لتمثيل الحرف (الحروف) ) مثل split("[.]")
، أو استخدم Pattern#quote()
للهروب من السلسلة بأكملها مثل split(Pattern.quote("."))
.
String[] parts = string.split(Pattern.quote(".")); // Split on period.
لاختبار ما إذا كانت السلسلة تحتوي على أحرف معينة ، استخدم فقط String#contains()
.
if (string.contains("-")) {
// Split it.
} else {
throw new IllegalArgumentException("String " + string + " does not contain -");
}
لاحظ أن هذا لا يأخذ تعبيرًا منتظمًا. لذلك ، استخدم String#matches()
بدلاً من ذلك.
إذا كنت ترغب في الاحتفاظ بحرف الانقسام في الأجزاء الناتجة ، فاستغل نظرة إيجابية . في حال كنت تريد أن ينتهي حرف الانقسام في الجانب الأيسر ، استخدم lookbehind الإيجابي عن طريق بادئة مجموعة ?<=
على النمط.
String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556
في حال كنت تريد أن ينتهي حرف الانقسام في الجانب الأيمن ، استخدم واجهة مظهر إيجابية عن طريق بادئة مجموعة ?=
على النمط.
String string = "004-034556";
String[] parts = string.split("(?=-)");
String part1 = parts[0]; // 004
String part2 = parts[1]; // -034556
إذا كنت ترغب في تحديد عدد الأجزاء الناتجة ، فيمكنك توفير العدد المطلوب كوسيطة ثانية لطريقة split()
.
String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42
بديل لمعالجة السلسلة مباشرة سيكون استخدام تعبير عادي مع مجموعات الالتقاط. هذا لديه ميزة أنه يجعل من السهل على فرض قيود أكثر تطورا على المدخلات. على سبيل المثال ، يقسم التالي السلسلة إلى جزأين ، ويضمن أن كلاهما يتكون فقط من أرقام:
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
String[] result = yourString.split("-");
if (result.length != 2)
throw new IllegalArgumentException("String not in correct format");
سيؤدي ذلك إلى تقسيم الخيط إلى قسمين. سيكون العنصر الأول في الصفيف هو الجزء الذي يحتوي على العناصر قبل -
، وسيحتوي العنصر الثاني في الصفيف على جزء السلسلة بعد -
.
إذا كان طول الصفيف 2 ، فلن تكون السلسلة بالتنسيق: string-string
.
تحقق من طريقة split()
في فئة String
.
https://docs.Oracle.com/javase/8/docs/api/Java/lang/String.html#split-Java.lang.String-int-
// 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[] out = string.split("-");
يجب أن تفعل الشيء الذي تريده. فئة السلسلة لديها العديد من الطرق للعمل مع السلسلة.
متطلبات ترك مجالا للتفسير. أوصي بكتابة طريقة
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]
أم أنه خطأ؟ وما إلى ذلك وهلم جرا.
باستخدام Java 8:
List<String> stringList = Pattern.compile("-")
.splitAsStream("004-034556")
.collect(Collectors.toList());
stringList.forEach(s -> System.out.println(s));
افترض أن
أسهل طريقة هي استخدام 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 ، لأنه عادة ما يحتوي على الكثير من الأشياء القابلة للاستخدام. ومع ذلك ، إذا لم تكن في حاجة إلى أي شيء آخر غير القيام بالانقسام ، فإن تطبيق نفسك أو الهروب من ريكس يعد خيارًا أفضل.
استخدم org.Apache.commons.lang.StringUtils ' split طريقة التي يمكن تقسيم السلاسل على أساس الحرف أو السلسلة التي تريد تقسيمها.
توقيع الطريقة:
public static String[] split(String str, char separatorChar);
في حالتك ، تريد تقسيم سلسلة عندما يكون هناك "-".
يمكنك ببساطة القيام بما يلي:
String str = "004-034556";
String split[] = StringUtils.split(str,"-");
الإخراج:
004
034556
افترض أنه في حالة عدم وجود -
في السلسلة ، فسوف تُرجع السلسلة المحددة ، ولن تحصل على أي استثناء.
يمكنك محاولة مثل هذا أيضا
String concatenated_String="hi^Hello";
String split_string_array[]=concatenated_String.split("\\^");
String Split مع أحرف متعددة باستخدام 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 ، ولكنه موجود في بعض الإصدارات بين الإصدارات الأحدث 1.7 من JDK و 1.8 الإصدارات المبكرة.
لحالات الاستخدام البسيط String.split()
يجب القيام بهذه المهمة. إذا كنت تستخدم الجوافة ، فهناك أيضًا Splitter class التي تسمح بسلسلة من عمليات السلسلة المختلفة وتدعم CharMatcher :
Splitter.on('-')
.trimResults()
.omitEmptyStrings()
.split(string);
أسرع طريقة ، والتي تستهلك أيضًا أقل مورد يمكن أن تكون:
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 '-'
}
لتلخيص: هناك خمس طرق على الأقل لتقسيم سلسلة في Java:
String.split ():
String[] parts ="10,20".split(",");
Pattern.compile (التعبير العادي) .splitAsStream (المدخلات):
List<String> strings = Pattern.compile("\\|")
.splitAsStream("010|020202")
.collect(Collectors.toList());
StringTokenizer (فئة قديمة):
StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", ".");
while(strings.hasMoreTokens()){
String substring = strings.nextToken();
System.out.println(substring);
}
جوجل الجوافة الفاصل:
Iterable<String> result = Splitter.on(",").split("1,2,3,4");
أباتشي العموم StringUtils:
String[] strings = StringUtils.split("1,2,3,4", ",");
بحيث يمكنك اختيار الخيار الأفضل لك اعتمادًا على ما تحتاج إليه ، على سبيل المثال نوع الإرجاع (صفيف ، قائمة ، أو قابلة للتكرار).
هنا هي نظرة عامة كبيرة على هذه الطرق والأمثلة الأكثر شيوعًا (كيفية القسمة على نقطة ، شرطة مائلة ، علامة استفهام ، إلخ.)
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 textStr[] = yourString.split("\\r?\\n");
يمكنك تقسيم سلسلة بواسطة واصلة/حرف باستخدام العبارة التالية:
String textStr[] = yourString.split("-");
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]);
}
}
}
يمكنك استخدام 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("-");
}
}
يرجى عدم استخدام StringTokenizer class لأنها فئة قديمة يتم الاحتفاظ بها لأسباب التوافق ، ويتم تثبيط استخدامها في التعليمات البرمجية الجديدة. ويمكننا الاستفادة من طريقة الانقسام كما اقترح البعض الآخر.
String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));
وكما هو متوقع ، ستتم طباعة:
[004, 034556]
في هذه الإجابة ، أود أيضًا الإشارة إلى تغيير واحد حدث لطريقة split
في Java 8 . تستخدم String # split () method Pattern.split
، والآن ستزيل السلاسل الفارغة في بداية صفيف النتائج. لاحظ هذا تغيير في وثائق Java 8:
عندما يكون هناك تطابق عرض موجب في بداية تسلسل الإدخال ، يتم تضمين سلسلة بادئة فارغة فارغة في بداية الصفيف الناتج. ومع ذلك ، لا تؤدي المطابقة ذات العرض الصفري في البداية إلى إنتاج هذه السلسلة الفرعية الفارغة.
وهذا يعني للمثال التالي:
String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));
سنحصل على ثلاث سلاسل: [0, 0, 4]
وليس أربعة كما كان الحال في Java 7 وما قبله. أيضا التحقق من هذا مماثل السؤال .
إحدى الطرق للقيام بذلك هي تشغيل السلسلة في حلقة لكل واستخدام حرف الانقسام المطلوب.
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
فيما يلي طريقتان لتحقيق ذلك.
الطريقة 1: بما أن عليك تقسيم رقمين بحرف خاص ، فيمكنك استخدام regex
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());
}
}
}
الطريقة 2: استخدام طريقة تقسيم السلسلة
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);
}
}
}
يمكنك ببساطة استخدام StringTokenizer لتقسيم سلسلة إلى جزأين أو أكثر سواء كان هناك أي نوع من المحددات:
StringTokenizer st = new StringTokenizer("004-034556", "-");
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
تحقق من طريقة split()
في فئة String
في javadoc.
https://docs.Oracle.com/javase/7/docs/api/Java/lang/String.html#split(Java.lang.String)
String data = "004-034556-1212-232-232";
int cnt = 1;
for (String item : data.split("-")) {
System.out.println("string "+cnt+" = "+item);
cnt++;
}
هنا العديد من الأمثلة على سلسلة الانقسام لكنني قليلا رمز الأمثل.
String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter
string1=004 // sTemp[0];
string2=034556//sTemp[1];
هناك طريقتان فقط تحتاجان إلى أخذها في الاعتبار.
استخدم String.split إذا كان محدد حرف واحد أو لا يهمك الأداء
إذا لم يكن الأداء مشكلة ، أو إذا كان المحدد هو حرف فردي لا يمثل حرفًا خاصًا للتعبير العادي (على سبيل المثال ، ليس واحداً من .$|()[{^?*+\
) ، فيمكنك استخدام String.split
.
String[] results = input.split(",");
تحتوي طريقة الانقسام على تحسين لتجنب استخدام تعبير عادي إذا كان المحدد هو حرف واحد وليس في القائمة أعلاه. خلاف ذلك ، يجب عليه تجميع تعبير عادي وهذا ليس مثاليًا.
استخدم Pattern.split وإعادة ترجمة النمط إذا كنت تستخدم محددًا معقدًا وتهتم بالأداء
إذا كان الأداء مشكلة ولم يكن المحدد الخاص بك هو واحد مما سبق ، فيجب أن تقوم مسبقًا بترجمة نمط تعبير عادي يمكنك إعادة استخدامه.
// Save this somewhere
Pattern pattern = Pattern.compile("[,;:]");
/// ... later
String[] results = pattern.split(input);
لا يزال هذا الخيار الأخير ينشئ كائن Matcher
جديدًا. يمكنك أيضًا تخزين هذا الكائن مؤقتًا وإعادة تعيينه لكل إدخال لتحقيق أقصى أداء ، لكن هذا الأمر أكثر تعقيدًا إلى حد ما وليس آمنًا بسلسلة الرسائل.
أردت فقط أن أكتب خوارزمية بدلاً من استخدام وظائف 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;
}
يمكنك استخدام طريقة تقسيم
public class Demo {
public static void main(String args[]){
String str ="004-034556";
if((str.contains("-"))){
String[] temp=str.split("-");
for(String part:temp){
System.out.println(part);
}
}else{
System.out.println(str+" does not contain \"-\".");
}
}
}
لتقسيم سلسلة ، استخدم String.split(regex)
:
String phone = "004-034556";
String[] output = phone.split("-");
System.out.println(output[0]);
System.out.println(output[1]);
انتاج:
004
034556
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 كوسيطة ، تذكر أن تفلت من الأحرف الخاصة بـ regex ، مثل الفترة/النقطة.