2012-06-14 3 views
2

У меня есть строка, используя символ трубы «| в качестве разделителя Однако строковые данные также содержит символ трубы Есть ли способ игнорировать этоJava - Игнорировать разделитель в строках

Пример:..?

name|address|age 

John|123 Wood Road|Street, London|25 

Поэтому, когда я делаю это -

text.split("\\|") 

дает мне:

John 

123 Wood Road 

Street, London 

25 

Я ожидал этого:

John 

123 Wood Road|Street, London 

25 
+4

Как человек, я не мог отличить разделитель от обычного бара. Синтаксически оба они окружены символами. Как бы вы предложили рассказать о различии даже с человеком? –

+0

Будет ли это всегда так? (Я имею в виду разделитель в полевом поле) –

+4

Можете ли вы использовать другой разделитель? –

ответ

6

String.split() не может различать различные вхождения одного и того же символа. Вам нужно будет ввести некоторые правила, как в коде, так и в регулярном выражении. На основании данных, я предполагаю, что в то время как вы говорите, что труба может иметь место в пределах строки данных, он действительно может не произойти в имени или возраста, так что вы могли бы сделать что-то вроде этого:

String[] results = text.split("\\|") 

String name = results[0]; 
String age = results[results.length - 1] 

String address = results[1]; 
for (int i = 2; i < results.length-1; i++) { 
    address = address + "|" + results[i]; 
} 
+0

что, если String text = "John | 123 Wood Road | Street | State, London | 25"; то вам снова нужно изменить свой pharser. –

+1

@AkhilDev Как так?Предполагается, что все, что находится между первым и последним каналом, является адресом, и цикл заботится о том, чтобы вернуть его обратно. – sharakan

+0

Спасибо Sharakan. Это даст вам шанс. –

1

Однако строковые данные также содержит символ трубы. Есть ли способ игнорировать это?

Это неправильный способ решения проблемы.

Если пользователь вводит имя, адрес и возраст, вы должны дезинфицировать их перед хранением.

Итак, как бы вы шлифовали пользовательский ввод в этом случае. Ну, вы, как правило, избежать любой введенный пользователем символ трубы с обратной косой чертой (до конкатенации окончательной строки), поэтому вместо того, чтобы хранить

John|123 Wood Road|Street, London|25 

вы бы хранить

John|123 Wood Road\|Street, London|25 

Таким образом, вы всегда можете получить назад, что вошел пользователь, по

  1. расщепления на неэкранированных символах трубы
  2. неэкранированных каждую часть.

Однако я рекомендую вам использовать библиотеку для этого, такую ​​как OpenCSV.

1

Простой ответ заключается в использовании другого разделителя.

Хотя это не является доказательством дурака, так как вы можете встретить новый разделитель как действительный символ в одной из ваших частей (имя, адрес или возраст).

Мое лучшее предложение состоит в том, чтобы включить какой-то escape-символ, чтобы не обрабатывать трубу в качестве разделительной трубы, когда она встречается. (Возможно, \ ???)

Я предполагаю, что вы знакомы с концепцией escape-символов, поскольку вы используете их в регулярном выражении, которое вы предоставляете String.split().

"Джон | 123 Лесная дорога \ | Street, London | 25"

1

ли это то, что вы ищете?

String text = "John|123 Wood Road|Street, London|25"; 

int first = text.indexOf("|"); 
int last = text.lastIndexOf("|"); 

String name = text.substring(0, first); 
String age = text.substring(last + 1); 
String address = text.substring(first + 1, last); 

System.out.println(name); 
System.out.println(address); 
System.out.println(age); 

ВЫХОД:

John 
123 Wood Road|Street, London 
25 

Более общее решение:

public static void main(String[] args) 
{ 
    String text = "John|123 Wood Road|Street, London|25"; 
    for(String s : getArray(text, 0, 1, 0)) System.out.println(s); 
} 

public static String[] getArray(String text, int... pipeCount) 
{ 
    String[] arr = text.split("\\|"); 
    String[] result = new String[3]; 

    int counter = 0; 
    for(int i = 0; i < result.length; i++) 
    { 
     result[i] = ""; 
     for(int j = 0; j <= pipeCount[i]; j++) result[i] += arr[counter++]; 
    } 
    return result; 
} 

ВЫХОД:

John 
123 Wood Road|Street, London 
25 
+0

Спасибо Fouad. Очень полезно. –

+0

Очень хорошо работает. Благодаря! –

1
  • В общем, вы не можете иметь что-либо, что является частью данных в качестве разделителя. Как вы можете отличить разделитель от данных, если они одинаковы? Способ обойти это использовать что-то необычное как разделитель, такой как двойной канал || или какой-либо другой шаблон, который менее вероятен для присутствия в данных.
  • Если возможно, вы можете использовать другие форматы данных, такие как XML, JSON, CSV и т. Д. Это гораздо лучшее решение, чем предыдущее, поскольку это всегда будет работать.
  • В этом конкретном случае, если вы уверены, что только адрес может содержать |, но имя и возраст не могут содержать |, то вы можете разделить его на |, сначала введите имя, фамилию, последний по возрасту и все части между ними как адрес , Если между ними имеется более одной части, тогда адрес содержит |. Затем вы можете присоединиться к средним частям с |, зная, что они являются частью адреса. Но это нехорошее решение, так как это не будет работать, если в первом и последнем поле разрешено |.
1

Вы можете каким-либо образом избежать ввода пользователем. Например, если ваш разделитель |, и ваши данные содержат один, измените его на что-то вроде %p (p для трубы!). Но тогда вам также придется избегать всех %. Сделайте это, когда вы сериализуете свои данные, а затем отмените его при десериализации.

Смежные вопросы