JavaRush /وبلاگ جاوا /Random-FA /روش تقسیم در جاوا: یک رشته را به قطعات تقسیم کنید

روش تقسیم در جاوا: یک رشته را به قطعات تقسیم کنید

در گروه منتشر شد
بیایید در مورد روش تقسیم رشته صحبت کنیم : چه کاری انجام می دهد و چرا به آن نیاز است. به راحتی می توان حدس زد که رشته را تقسیم می کند، اما در عمل چگونه کار می کند؟ بیایید نگاهی دقیق‌تر به نحوه عملکرد متد بیندازیم و در مورد جزئیات غیر آشکار بحث کنیم، و در عین حال دریابیم که واقعاً چند متد تقسیم در کلاس String وجود دارد. بیا بریم!

تعریف و امضای جاوا String.split

متد split در جاوا یک رشته را با استفاده از یک جداکننده که با استفاده از یک عبارت منظم مشخص شده است به زیر رشته ها تقسیم می کند. بیایید امضای روش را بدهیم و شیرجه خود را شروع کنیم:
String[] split(String regex)
دو چیز از امضا مشخص است:
  1. متد آرایه ای از رشته ها را برمی گرداند.
  2. این روش یک رشته regex را به عنوان پارامتر می گیرد.
بیایید با توجه به تعریفی که در بالا ارائه شد، به هر چیز جداگانه نگاه کنیم.
  1. متد آرایه ای از رشته ها را برمی گرداند.

    این تعریف حاوی کلمات زیر است: " روش تقسیم در جاوا یک رشته را به زیر رشته ها تقسیم می کند." این زیر رشته ها توسط متد در یک آرایه جمع آوری می شوند و مقدار بازگشتی آن را نشان می دهند.

  2. این روش یک رشته regex را به عنوان پارامتر می گیرد.

    باز هم، این تعریف را به خاطر بسپارید: "رشته ای را با استفاده از یک جداکننده که با استفاده از یک عبارت منظم مشخص شده است به زیر رشته ها تقسیم می کند." پارامتر regex پذیرفته شده یک الگوی عبارت منظم است که به رشته منبع اعمال می شود و با کاراکتر جداکننده (یا ترکیبی از کاراکترها) در رشته منبع مطابقت دارد.

روش تقسیم در جاوا: یک رشته را به قسمت های - 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" جداکننده: " " آرایه حاصل: { "I" , "love" , "Java" } ما در کد به تغییرات متد split نگاه می کنیم. با یک کاراکتر جداکننده در پایان و/یا ابتدای رشته منبع:
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)
این روش دارای یک پارامتر محدود اضافی است : تعداد دفعاتی که الگوی regex روی رشته منبع اعمال می شود را تعیین می کند. در زیر توضیحات ارائه شده است:

حد > 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));
    }
}
اگر به پیاده سازی متد split با یک آرگومان نگاه کنیم، می بینیم که این متد، برادر بارگذاری شده خود را با آرگومان دوم صفر فراخوانی می کند:
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]
    }
}
به جداکننده توجه کنید: "\\|" . از آنجایی که در عبارات منظم "|" - این یک کاراکتر خاص است که منطق خاصی روی آن گره خورده است؛ برای اینکه از آن به عنوان یک کاراکتر معمولی استفاده کنیم (همانی که می خواهیم در رشته منبع پیدا کنیم)، باید با استفاده از دو اسلش از این کاراکتر فرار کنیم. بیایید به مثال دیگری نگاه کنیم. فرض کنید اطلاعاتی در مورد یک سفارش داریم که تقریباً در این قالب نوشته شده است:
آیتم_شماره_1، نام_مورد_1، قیمت_اقلام_1;شماره_مورد_2،نام_مورد_2،قیمت_مورد_2؛...;شماره_مورد_n،نام_مورد_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;
    }
}
سعی کنید خودتان بفهمید که این روش چگونه کار می کند. با توجه به این مثال‌ها می‌توان گفت که از روش تقسیم زمانی استفاده می‌شود که اطلاعاتی به صورت رشته‌ای داشته باشیم که باید اطلاعات خاص تری را از آن استخراج کنیم.

نتایج

ما به متد split کلاس String نگاه کردیم . برای تقسیم یک رشته به اجزای سازنده آن با استفاده از یک جداکننده خاص لازم است. متد آرایه ای از رشته ها (اجزای یک رشته) را برمی گرداند. یک عبارت منظم را می‌پذیرد که نویسه(های) جداکننده را پیدا می‌کند. ما به ظرافت های مختلف این روش نگاه کردیم:
  • شخصیت جداکننده پیشرو;
  • برادر بیش از حد با دو استدلال.
ما همچنین سعی کردیم برخی از موقعیت‌های «زندگی واقعی» را شبیه‌سازی کنیم که در آن‌ها از روش تقسیم برای حل مشکلات هرچند ساختگی، اما کاملاً واقعی استفاده کردیم .
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION