Как найти разделитель элементов в строке?

У меня есть строка, например "option1;option2;option3", где ";" разделитель может быть любым. Любая строка, состоящая не менее чем из 1 символа, которую вводит пользователь.

Я ищу простой/чистый способ определить разделитель без какой-либо информации, кроме входной строки.

Я могу гарантировать, что разделитель существует только между двумя элементами, но учтите возможность только одного параметра во входной строке. Я также могу гарантировать, что разделитель не будет буквенно-цифровым и может содержать пробел и $ или # или % и т. д.

Не удалось создать регулярное выражение для этого, но, возможно, кто-то сможет, хотя я особо не ищу регулярное выражение.


person Discipol    schedule 24.10.2013    source источник
comment
Каким должен быть разделитель в hello world; goodbye world?   -  person Jon    schedule 24.10.2013
comment
Есть ли в строке не буквенно-цифровые символы, кроме разделителей?   -  person Bernhard Barker    schedule 24.10.2013
comment
разделитель существует только между двумя элементами, это не очень полезная информация. Трудно, чтобы что-то находилось между более чем двумя или менее чем двумя элементами в строке. Ваша проблема некорректна.   -  person BartoszKP    schedule 24.10.2013
comment
@ Джон, это было бы ;   -  person Discipol    schedule 24.10.2013
comment
@Discipol: И незаданный вопрос: как вы можете сказать? Почему бы не просто ; или просто пробел? А как насчет hello world;goodbye world? Здесь ; или пробел? Опять же, как вы можете сказать?   -  person Jon    schedule 24.10.2013
comment
@BartoszKP у вас его не будет option1;option2; Что-то может быть не между 2 элементами.   -  person Discipol    schedule 24.10.2013
comment
@Discipol Это не между чем-либо, не нужно считать элементы. Но я понимаю вашу точку зрения, это ограничение кажется нормальным. Тем не менее проблема Дюклинга по-прежнему доказывает, что здесь существует неразрешимая двусмысленность, поскольку вы позволяете пространству быть разделителем.   -  person BartoszKP    schedule 24.10.2013
comment
@Jon его пробел И такие символы, как #@$!   -  person Discipol    schedule 24.10.2013
comment
@Discipol Возможно, улучшите вопрос, может содержать пробел и ... также может быть интерпретировано как может содержать пробел и может содержать другие символы.   -  person BartoszKP    schedule 24.10.2013


Ответы (2)


Чтобы найти разделитель

in = "option1;option2;option3"
separator=re.search("[ ;'#/.,<>?~@;,:}{\]\[+=\-_]+", in).group()

Извините, для этого было проще использовать регулярное выражение

Теперь он вернулся к вам. Вам нужно доказать, что это работает так, как вы намеревались, против всех возможных входных данных.

Вот, возможно, более простая в использовании версия

possible=""" ;'#/.,<>?~@,:}{][+=-_"""
seperator=re.search("[%s]+" % re.escape(possible), input).group()

Это означает, что символы со специальным значением в регулярном выражении могут быть добавлены или удалены проще.

person Vorsprung    schedule 24.10.2013
comment
ну не все возможные входы, только самые обычные пользователи будут вводить. давать пользователю плохую ошибку ввода — это все равно, что говорить, что вы хреново разбираетесь в компьютерах и нуждаетесь в этом, чтобы позаботиться о таких вещах. Пользователь, скорее всего, будет использовать или ; или же ; или же , - person Discipol; 24.10.2013

Это сработало бы только в том случае, если бы вы точно знали, что только символы [A-Za-z0-9_] будут отображаться в полях inf: ^(\w+)\W(\w+)\W(\w+)$

Вероятно, это не так, поэтому мое решение было бы следующим:

  1. Создайте список всех возможных разделителей.
  2. Для каждого из этих разделителей запустите регулярное выражение (динамически построенное в цикле): ^([^X]+)X([^X]+)X([^X]+)$, где X — символ-разделитель.
  3. Проверьте, равно ли количество совпадений ожидаемому количеству столбцов (или перейдите к 4, если вы не знаете количество столбцов).
  4. Запустите его для каждой строки, чтобы увидеть, изменилось ли количество совпадений, потому что совпадение в первой строке может быть слепой удачей.
  5. Если он совпадает везде, то у вас есть свой разделитель и количество столбцов. Если он не совпадает, начните проверять следующий разделитель для каждой строки.

Недостатком этого решения является то, что в худшем случае вы будете запускать свое регулярное выражение для каждой строки текста и для каждого разделителя. Возможные оптимизации:

  1. Сначала начните проверку с наиболее распространенных разделителей
  2. Вместо того, чтобы запускать регулярное выражение для каждой строки для каждого разделителя, просто подсчитайте количество символов разделителя во всем тексте. Если количество строк без остатка делится на количество символов-разделителей, то велика вероятность того, что разделитель действителен.
person AdamL    schedule 24.10.2013