CodeGym /בלוג Java /Random-HE /שיטת Java String.split()‎
John Squirrels
רָמָה
San Francisco

שיטת Java String.split()‎

פורסם בקבוצה
בואו נדבר על שיטת String.split של Java : מה היא עושה ולמה היא נחוצה. לא קשה לנחש שזה מפצל מחרוזת Java, אבל איך זה עובד בפועל? בואו נצלול עמוק לתוך פעולת השיטה ונדון בכמה פרטים לא מובנים מאליהם. במקביל, נלמד כמה שיטות פיצול יש למחרוזת בפועל. בוא נלך!

תיאור וחתימה עבור String.split של Java

ב-Java, שיטת הפיצול מפצלת מחרוזת למחרוזות משנה באמצעות מפריד המוגדר באמצעות ביטוי רגולרי. בואו נציג את חתימת השיטה ונתחיל את הצלילה שלנו:

String[] split(String regex)
שני דברים ברורים מהחתימה:
  1. השיטה מחזירה מערך של מחרוזות.
  2. לשיטה יש פרמטר קלט מחרוזת שנקרא regex .
הבה ננתח כל אחד מאלה בנפרד כאשר אנו מפרקים את התיאור שניתן לעיל.
  1. השיטה מחזירה מערך של מחרוזות.

    ההצהרה מכילה את המילים הבאות: "ב-Java, שיטת הפיצול מפצלת מחרוזת למחרוזות משנה." השיטה אוספת את מחרוזות המשנה הללו למערך שהופך לערך ההחזרה.

  2. לשיטה יש פרמטר קלט מחרוזת שנקרא regex .

    שוב, זכור את התיאור: "מפצל מחרוזת למחרוזות משנה באמצעות מפריד המוגדר באמצעות ביטוי רגולרי." פרמטר הקלט הרגולרי הוא ביטוי רגולרי שמוחל על המחרוזת המקורית. כאשר התו או שילוב התווים תואמים, מתייחסים אליהם כאל תוחם.

שיטת String.split() ב-Java: פיצול מחרוזת לחלקים - 1

ג'אווה התפצלה בפועל

עכשיו בואו נתקרב לנקודה. בואו נדמיין שיש לנו מחרוזת של מילים. לדוגמה, כך:
אני אוהב ג'אווה
אנחנו צריכים לפצל את המחרוזת למילים. אנו רואים שהמילים במחרוזת זו מופרדות זו מזו על ידי רווחים. במקרה זה, תו רווח הוא המועמד המושלם לתוחם שלנו. הקוד לפתרון המשימה שלנו ייראה כך:

public class Main {
    public static void main(String[] args) {
        String str = "I love Java";
        String[] words = str.split(" ");
        for (String word : words) {
            System.out.println(word);
        }
    }
}
הפלט של השיטה הראשית יהיה השורות הבאות:
אני אוהב ג'אווה
בואו נראה עוד כמה דוגמאות לאופן שבו שיטת הפיצול תעבוד:
חוּט תוחם תוצאה של השיטה
"אני אוהב ג'אווה" " " (תו רווח) { "אני" , "אהבה" , "ג'אווה" }
"192.168.0.1:8080" ":" { "192.168.0.1" , "8080" }
"אדום, כתום, צהוב" "," { "אדום" , "כתום" , "צהוב" }
"אדום, כתום, צהוב" "," { "אדום" , "כתום" , "צהוב" }
שימו לב להבדלים בין שתי השורות האחרונות בטבלה למעלה. בשורה השנייה עד האחרונה, פסיק משמש כמפריד. כתוצאה מכך, כאשר המחרוזת מפוצלת, לחלק מהמילים יש רווחים מובילים. בשורה האחרונה, השתמשנו בפסיק וברווח כמפריד. זו הסיבה שלא היו תת מחרוזות עם רווחים מובילים במערך שהתקבל. זהו רק פרט עדין שמדגים עד כמה חשוב לבחור בקפידה את התוחם הנכון.

תוחם מוביל

זה עוד ניואנס חשוב. אם המחרוזת המקורית מתחילה במפריד, אז הרכיב הראשון של המערך המתקבל יהיה מחרוזת ריקה. לדוגמה, זה ייראה כך: מחרוזת מקורית: "I love Java" מפריד: " " מערך המתקבל: { "", "I", "love", "Java" } אבל אם המחרוזת המקורית מסתיימת במפריד. מאשר להתחיל באחד, אז התוצאה תהיה שונה: מחרוזת מקורית: "I love Java " Delimiter: " " מערך המתקבל: { "I", "love", "Java" } תסתכל על הקוד וראה כיצד שיטת הפיצול עובד אחרת עם סמל מפריד בסוף ו/או בתחילת המחרוזת המקורית:

public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" "));
        print(" I love Java".split(" "));
        print("I love Java ".split(" "));
        print(" I love Java ".split(" "));
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
הפלט של השיטה הראשית יהיה כך:
[אני, אוהב, ג'אווה] [, אני, אוהב, ג'אווה] [אני, אוהב, ג'אווה] [, אני, אוהב, ג'אווה]
שוב הפנה את תשומת לבך לעובדה שכאשר התו הראשון במחרוזת המקורית הוא תו מפריד, אז התוצאה היא שהאלמנט הראשון במערך יהיה מחרוזת ריקה.

אח עמוס מדי

למחלקה String יש שיטת פיצול נוספת עם החתימה הבאה:

String[] split(String regex, int limit)
לשיטה זו יש פרמטר מגבלה נוסף : היא קובעת כמה פעמים תבנית הביטוי הרגולרי יוחל על המחרוזת המקורית. ראה את ההסברים למטה:

מגבלה > 0

הדפוס מיושם מגבלה -1 פעמים. מה גם שאורך המערך המוחזר לא יעלה על הערך של פרמטר הגבול . האלמנט האחרון של המערך יהיה החלק של המחרוזת שעוקב אחרי המקום האחרון שבו נמצא המפריד. דוגמא:

public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" ", 1));
        print("I love Java".split(" ", 2));
        /*
         Output: 
         [I love Java]
         [I, love Java]
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

מגבלה < 0

הביטוי הרגולרי המפריד מוחל על המחרוזת פעמים רבות ככל האפשר. למערך המתקבל יכול להיות כל אורך. דוגמא:

public class Main {
    public static void main(String[] args) {
        // Note the space at the end of the string
        print("I love Java ".split(" ", -1));
        print("I love Java ".split(" ", -2));
        print("I love Java ".split(" ", -12));
        /*
         Output:
        [I, love, Java, ]
        [I, love, Java, ]
        [I, love, Java, ]
        
        Please note that the last element of the array is
        an empty string. This is caused by the whitespace
        at the end of the original string. 
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

הגבלה = 0

כמו במקרה שבו מגבלה < 0, תבנית המפריד מוחלת על המחרוזת כמה פעמים שאפשר. למערך הסופי יכול להיות כל אורך. אם האלמנטים האחרונים הם מחרוזות ריקות, הם נמחקים מהמערך הסופי. דוגמא:

public class Main {
    public static void main(String[] args) {
        // Note the space at the end of the string
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        /*
         Output:
        [I, love, Java]
        [I, love, Java]
        [I, love, Java]
        Note the absence of empty strings at the end of the arrays
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
אם נציץ ביישום הגרסה בעלת הפרמטר האחד של שיטת הפיצול , אזי נוכל לראות שהיא דומה לאחיו העמוס יתר על המידה, אבל כשהארגומנט השני מוגדר לאפס:

    public String[] split(String regex) {
        return split(regex, 0);
    }

דוגמאות שונות

בתרגול בעולם האמיתי, קורה לפעמים שיש לנו מחרוזות שנוצרות על פי כללים מסוימים. מחרוזת כזו עשויה להיכנס לתוכנית שלנו מכל מקום:
  • משירות של צד שלישי;
  • מבקשה שנשלחה לשרת שלנו;
  • מקובץ תצורה;
  • וכולי.
במצבים אלו, המתכנת בדרך כלל מכיר את "כללי המשחק". נניח שמתכנת יודע שהוא או היא מתמודדים עם מידע משתמש המאוחסן לפי הדפוס הזה:
user_id|user_login|user_email
ניקח כמה ערכים ספציפיים כדוגמה:
135|bender|bender@gmail.com
נניח שהמשימה של המתכנת היא לכתוב שיטה ששולחת מייל למשתמש. למתכנת יש גישה לנתוני משתמש, אשר מתועדים בפורמט המפורט לעיל. תת-המשימה שכעת נמשיך לנתח היא כיצד לבודד את כתובת המייל משאר נתוני המשתמש. זהו מקרה אחד שבו שיטת הפיצול יכולה להיות שימושית. אחרי הכל, אם אנחנו מסתכלים על תבנית הנתונים של המשתמש, אנחנו מבינים שחילוץ כתובת הדוא"ל של המשתמש מהשאר היא פשוטה כמו קריאה לשיטת הפיצול כדי לפצל את המחרוזת. אז כתובת הדוא"ל תהיה ברכיב האחרון של המערך שיתקבל. הנה דוגמה לשיטה שלוקחת מחרוזת המכילה נתוני משתמש ומחזירה את כתובת האימייל של המשתמש. לשם הפשטות, נניח שמחרוזת הנתונים היא תמיד בפורמט שאנחנו רוצים:

public class Main {
    public static void main(String[] args) {
        String userInfo = "135|bender|bender@gmail.com";
        System.out.println(getUserEmail(userInfo));
        // Output: bender@gmail.com
    }

    static String getUserEmail(String userInfo) {
        String[] data = userInfo.split("\\|");
        return data[2]; // or data[data.length - 1]
    }
}
שימו לב למפריד: "\\|" . בביטויים רגולריים, "|" הוא תו מיוחד עם משמעות מיוחדת, אז אם אנחנו רוצים להשתמש בו בתו רגיל (כלומר מה שאנחנו רוצים למצוא במחרוזת המקורית), אז אנחנו צריכים לברוח מהתו עם שני קווים אחוריים. שקול דוגמה נוספת. נניח שיש לנו מידע הזמנה בנוי כך:
item_number_1,item_name_1,item_price_1;item_number_2,item_name_2,item_price_2;...;item_number_n,item_name_n,item_price_n
או שנוכל אפילו לאמץ כמה ערכים ספציפיים:
1,מלפפונים,2.39;2,עגבניות,1.89;3,בייקון,4.99
המשימה שלנו היא לחשב את העלות הכוללת של ההזמנה. כאן נצטרך ליישם את שיטת הפיצול מספר פעמים. הצעד הראשון הוא לפצל את המחרוזת באמצעות ";" בתור התוחם על מנת לפרק אותו לחלקיו המרכיבים. אז כל תת-מחרוזת שתתקבל תכיל מידע על מוצר נפרד, אותו נוכל לעבד מאוחר יותר. לאחר מכן, עבור כל מוצר, נחלק את המידע המתאים באמצעות הסמל ",". ניקח אלמנט עם אינדקס ספציפי (זה שבו מאוחסן מחיר המוצר) ממערך המחרוזות המתקבל, נמיר אותו לצורה מספרית ונמנה את העלות הכוללת של ההזמנה. בוא נכתוב שיטה שתעשה את כל החישובים האלה:

public class Main {
    public static void main(String[] args) {
        String orderInfo = "1,cucumbers,2.39;2,tomatoes,1.89;3,bacon,4.99";
        System.out.println(getTotalOrderAmount(orderInfo));
        // Output: 9.27
    }

    static double getTotalOrderAmount(String orderInfo) {
        double totalAmount = 0d;
        final String[] items = orderInfo.split(";");

        for (String item : items) {
            final String[] itemInfo = item.split(",");
            totalAmount += Double.parseDouble(itemInfo[2]);
        }

        return totalAmount;
    }
}
בדוק אם אתה יכול להבין איך שיטה זו עובדת בעצמך. בהתבסס על דוגמאות אלו, אנו יכולים לומר ששיטת הפיצול משמשת כאשר יש לנו כמה נתונים המעוצבים כמחרוזת, ועלינו לחלץ ממנו מידע מסוים יותר ספציפי.

סיכום

בדקנו את שיטת הפיצול של המחלקה String . זה בדיוק מה שאתה צריך כשאתה צריך לפצל מיתר לחלקים המרכיבים אותו בעזרת תוחם מיוחד. השיטה מחזירה מערך של מחרוזות (מחרוזות המשנה המרכיבות את המחרוזת המקורית). הוא מקבל ביטוי רגולרי שההתאמות שלו מייצגות את התווים המפרידים. בדקנו דקויות שונות של שיטה זו:
  • תוחם מוביל;
  • אחיו העמוס עם שני פרמטרים.
ניסינו גם לדגמן כמה מצבים בחיים האמיתיים שבהם השתמשנו בשיטת הפיצול כדי לפתור בעיות היפותטיות, אבל די מציאותיות.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION