По сути, я получаю путь к файлу из строки внутри CSV-файла. Однако по какой-то причине программа, создающая файл CSV, удаляет двоеточие из строки, поэтому я получаю путь к файлу, который не работает внутри Java. Типичный вывод — /x/Rest/Of/Path
, где x — буква диска, но иногда может быть x/
вместо /x/
. По сути, мне нужно добавить двоеточие после буквы диска, если его еще нет; изменение /x/
или x/
на x:/
. Я уверен, что в основном это делается с помощью регулярных выражений, но я все еще пытаюсь понять основы регулярных выражений, поэтому я не уверен, как это написать. Заранее благодарю за любую помощь.
Добавьте двоеточие к пути к файлу после буквы диска (т.е. измените /c/ или c/ на c:/) в Java
Ответы (1)
Вот, попробуйте это и изучите, чтобы узнать, как это работает:
String path = "/C/Rest/Of/Path";
Pattern p = Pattern.compile("^(/?[CDEFGH])/");
Matcher m = p.matcher(path);
String pathWithColon = m.replaceAll("$1:/");
Вот руководство:
^
известен как якорь. Он соответствует самому началу строки. Без него это регулярное выражение также соответствовало бы/foo/C/Rest/Of/Path
, а нам это не нужно.?
может означать разные вещи, в зависимости от того, где он появляется. Если он не следует сразу за открывающей скобкой(
, не следует сразу за квантификатором*
,+
, другой?
,{n}
,{m,n}
, не появляется внутри класса символов< /em>[]
, а не экранированный\?
, то это квантификатор, означающий "0 или 1 предыдущего объекта", в данном случае/
. Думайте об этом как о «необязательном» операторе.[CDEFGH]
известен как класс символов. Это означает: «Любой один из этих символов». Вы можете отменить класс символов следующим образом:[^CDEFGH]
; это будет означать «Любой один символ, но не эти». Если вы хотите принять любую заглавную букву, вы можете использовать диапазон:[A-Z]
. Если вы хотите принять любое письмо, то:[a-zA-Z]
.- Круглые скобки, окружающие большую часть регулярного выражения, известны как группа захвата или группа захвата. Он «спасает» все, что «поймано» между ними.
- Во время замены вы можете ссылаться на «сохраненные» (захваченные) группы по
$1
,$2
,$3
и так далее. (Таким образом, вы можете захватить более одной группы; каждая захватываемая группа нумеруется в порядке открывающей скобки.) Обратите внимание, что в приведенном выше примере я также захватил/?
, поэтому, если косая черта существует, то она будет существовать в вывод тоже, а если нет, то нет.
Приятного обучения!
ИЗМЕНИТЬ
Я должен был привести пример более простого подхода для начала. Мои извинения. Это также подойдет:
String path = "/C/Rest/Of/Path";
path = path.replaceAll("^(/?[CDEFGH])/", "$1:/");
Использование скомпилированного шаблона только добавляет эффективности. Например, если вы собираетесь заменить массив из 10 000 путей, вы должны скомпилировать шаблон один раз, а затем использовать сопоставитель для замены каждого пути в цикле. (Без компиляции движку приходится анализировать шаблон с нуля для каждого встречающегося пути.)
person
slackwing
schedule
30.04.2013
Вау, рад, что спросил. Забудьте о регулярном выражении, я еще даже не был знаком с частью
Matcher
. Теперь я лучше понимаю регулярное выражение, просто не уверен, что в нем делают () . Я знаю, что ^ указывает начало строки, а /? означает, если первый / существует правильно? тогда [] для поиска одного из содержащихся символов перед другим /.
- person DGolberg; 01.05.2013
@DGolberg - я отредактировал свой ответ с объяснением частей. Пожалуйста, не стесняйтесь комментировать снова, если что-то неясно.
- person slackwing; 01.05.2013
Красиво, спасибо за заметки! Они были намного полезнее, чем многие другие сайты, которые я посетил в отношении регулярных выражений! Первоначально я пытался сделать что-то с помощью
.replace();
, но быстро понял, что мне придется использовать что-то еще, например .replaceall();
, но я не был знаком с ним. Мой опыт до сих пор заключался в основном в замене тега формата файла в конце имени файла или проверке определенного слова в строке (в основном .contains()
).
- person DGolberg; 01.05.2013
Основываясь на вашем последнем редактировании, исходный ответ, вероятно, в любом случае более правильный для моей ситуации, но второй экземпляр также пригодится. В основном я загружаю список завершенных корневых папок проекта в массив, а затем просматриваю их, чтобы получить список их файлов для загрузки.
- person DGolberg; 01.05.2013
@DGolberg - понятно; похоже, вы были на правильном пути. Оглядываясь назад, регулярное выражение кажется простым, но может быть пугающим до первого шага. Удачи в остальном!
- person slackwing; 01.05.2013
Конечно есть! Спасибо еще раз за помощь!
- person DGolberg; 01.05.2013