Розділити рядок з крапкою в якості роздільника


99

Мені цікаво, чи збираюся я .правильно розколоти рядок ? Мій код:

String[] fn = filename.split(".");
return fn[0];

Мені потрібна лише перша частина рядка, тому я повертаю перший елемент. Я запитую, тому що я помітив в API, що .означає будь-який символ, тому зараз я застряг.

Відповіді:


173

split()приймає регулярний вираз, тому вам потрібно втекти, .щоб не розглядати його як мета-символ регулярних виразів . Ось приклад:

String[] fn = filename.split("\\."); 
return fn[0];

17

Спліт використовує регулярні вирази, де "." це особливий символ, що означає будь-що. Вам потрібно уникнути цього, якщо ви дійсно хочете, щоб він відповідав знаку "." персонаж:

String[] fn = filename.split("\\.");

(один '\', щоб уникнути '.' у регулярному виразі, а другий, щоб уникнути першого в рядку Java)

Також я б не пропонував повертати fn [0], оскільки якщо у вас є файл із іменем something.blabla.txt, яке є дійсним іменем, ви не повернете фактичне ім'я файлу. Натомість я думаю, що краще, якщо ви використовуєте:

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);

Питання позначене Java, а не Javascript, з чим ви пов’язані.
Андрій Фірбінтеану

17

Тут я бачу лише рішення, але повного пояснення проблеми немає, тому я вирішив опублікувати цю відповідь

Проблема

Вам потрібно знати кілька речей text.split(delim). splitметод:

  1. приймає як аргумент регулярний вираз (регулярний вираз), який описує роздільник, на який ми хочемо розділити,
  2. якщо delimіснує в кінці типу textlike in a,b,c,,(де є роздільник ,) splitспочатку створить масив like, ["a" "b" "c" "" ""]але оскільки в більшості випадків нам насправді не потрібні ці кінцеві порожні рядки, він також автоматично видаляє їх для нас. Таким чином, він створює інший масив без цих трейлінг порожніх рядків і повертає його .

Вам також потрібно знати, що крапка. має особливий характер у регулярному вираженні . Він представляє будь-який символ (крім роздільників рядків, але це можна змінити Pattern.DOTALLпрапором).

Тож для рядка, як, "abc"якщо ми розділимо на "." splitметод буде

  1. створити масив, як ["" "" "" ""],
  2. але оскільки цей масив містить лише порожні рядки, і всі вони є слідами, вони будуть видалені (як показано в попередньому другому пункті)

це означає, що ми отримаємо в результаті порожній масив [](без елементів, навіть порожнього рядка), тому ми не можемо використовувати, fn[0]оскільки немає індексу 0.

Рішення

Щоб вирішити цю проблему, вам просто потрібно створити регулярний вираз, який буде представляти крапку. Для цього нам потрібно уникнути цього .. Існує небагато способів це зробити, але найпростіший - це, мабуть, використання \(що в рядку потрібно писати як, "\\"оскільки \там також є особливим і вимагає уникнення іншого \).

Тож рішення вашої проблеми може виглядати так

String[] fn = filename.split("\\.");

Бонус

Ви також можете використовувати інші способи втечі від такої точки

  • за допомогою класу символів split("[.]")
  • загортаючи його в цитату split("\\Q.\\E")
  • використовуючи належний зразок шаблону з Pattern.LITERALпрапором
  • або просто скористайтеся split(Pattern.quote("."))і дозвольте, щоб регулярний геть вийшов для вас.

це .. Мені дуже подобається: split("[.]")
Dragonborn

15

метод String # split (String) використовує регулярні вирази. У регулярних виразах "". символ означає "будь-який символ". Ви можете уникнути такої поведінки, уникаючи "".

filename.split("\\.");

або розповісти метод розділення на розділ у класі символів:

filename.split("[.]");

Класи символів - це колекції символів. Ви могли написати

filename.split("[-.;ld7]");

і ім'я файлу розділятиметься на кожне "-", ".", ";", "l", "d" або "7". Всередині класів символів "". не є особливим символом ("метахарактер").


@MisterSmith Ви можете поглянути тут на мову програмування. Ми говоримо про java, а не JavaScript.
f1sh

Ти абсолютно правий. Вчора я втомився, кодуючи обидві мови, не помітив типи даних Java. Я вважав, що, можливо, відповіді були правильними ще в 2010 році, але чомусь браузери сьогодні поводилися по-іншому.
Містер Сміт

7

Оскільки DOT (.) Розглядається як особливий символ і метод розділення String очікує регулярного виразу, який потрібно зробити так -

String[] fn = filename.split("\\.");
return fn[0];

У Java особливих символів потрібно уникнути символом "\", але оскільки "\" також є спеціальним символом на Java, вам потрібно уникнути цього знову за допомогою іншого "\"!



2

Чи не було б більш ефективно використовувати

 filename.substring(0, filename.indexOf("."))

якщо ви хочете лише те, що до першої крапки?


2

Зазвичай його НЕ гарна ідея розкрити його вручну. Для цього завдання в класі Шаблон існує метод:

java.util.regex
static String quote(String s) 


0

Примітка. Подальшу обережність слід виконувати з цим фрагментом, навіть після крапки!

Якщо ім'я файлу - це лише рядок ".", Тоді fn все одно буде дорівнює 0, а fn [0] все одно викине виняток!

Це тому, що якщо шаблон збігається принаймні один раз, тоді split відкине всі порожні порожні рядки (отже, і той, що знаходиться перед крапкою!) З масиву, залишаючи порожній масив для повернення.


Найпростішим рішенням у подібному випадку є також передати обмеження-аргумент 2 для виклику розбиття: String [] fn = filename.split ("[.]", 2);
avl42


0

За допомогою ApacheCommons це найпростіше:

File file = ...
FilenameUtils.getBaseName(file.getName());

Зауважте, він також витягує ім'я файлу з повного шляху.


-2

splitбере аргумент як аргумент. Тож вам слід пройти "\."замість того, "."що "."це метахарактер у регулярному вираженні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.