JavaRush /בלוג Java /Random-HE /שיטת פיצול ב-Java: מחלקים מחרוזת לחלקים

שיטת פיצול ב-Java: מחלקים מחרוזת לחלקים

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

הגדרה וחתימה עבור Java String.split

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

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

  2. השיטה לוקחת מחרוזת רגקס כפרמטר.

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

שיטת פיצול בג'אווה: מחלקים מחרוזת לחלקים - 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" }
"אדום, כתום, צהוב" "," { "אדום" , "כתום" , "צהוב" }
"אדום, כתום, צהוב" "," { "אדום" , "כתום" , "צהוב" }
שימו לב להבדלים בין שתי השורות האחרונות בטבלה למעלה. בשורה הלפני אחרונה, המפריד הוא פסיק, ולכן השורה מפוצלת כך שלחלק מהמילים יש רווחים מובילים. בשורה האחרונה השתמשנו בפסיק ובתו רווח כמפריד. לכן, המערך שהתקבל לא הכיל קווים עם רווחים מובילים. זהו רק פרט קטן שמדגים עד כמה חשוב לבחור בקפידה את המפריד הנכון.

תוחם מוביל

יש עוד ניואנס חשוב אחד. אם מחרוזת המקור מתחילה במפריד, האלמנט הראשון של המערך המתקבל יהיה המחרוזת הריקה. בדוגמה, זה ייראה כך: מחרוזת מקור: "אני אוהב את Java" מפריד: " " מערך המתקבל: { "" , "I" , "love" , "Java" } אבל אם מחרוזת המקור מסתיימת במפריד ולא מתחיל, התוצאה תהיה שונה: מחרוזת מקור: "I love Java" מפריד: " " מערך המתקבל: { "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) {
        // Notice the space at the end of the line
        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, ]

        Note that the last element of the array is
        an empty string, resulting from the space
        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) {
        // Notice the space at the end of the line
        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, מלפפונים, 20.05; 2, עגבניות, 123.45; 3, ארנבות, 0.50
לפנינו המשימה של חישוב העלות הכוללת של ההזמנה. כאן נצטרך להשתמש בשיטת הפיצול מספר פעמים. הצעד הראשון הוא לפצל את המחרוזת דרך הסמל ";" לחלקים המרכיבים אותה. ואז בכל חלק כזה יהיה לנו מידע על מוצר בודד, אותו נוכל לעבד בעתיד. ואז, בתוך כל מוצר, נפריד את המידע באמצעות הסמל "," וניקח מהמערך המתקבל אלמנט עם אינדקס מסוים (בו המחיר מאוחסן), נמיר אותו לצורה מספרית ונרכיב את העלות הסופית. של ההזמנה. בוא נכתוב שיטה שתחשב את כל זה:
public class Main {
    public static void main(String[] args) {
        String orderInfo = "1, cucumbers, 20.05; 2, tomatoes, 123.45; 3, hares, 0.50";
        System.out.println(getTotalOrderAmount(orderInfo));
        // Output: 144.0
    }

    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