Как я могу разбить эту строку?

Я пытаюсь разбить строки, предшествующие местам, где есть целое, 2-значное число, окруженное пробелами. В конце концов я бы хотел, чтобы это работало на Python, но я работал с sed, и я не могу понять это.

Мои тестовые данные выглядят так:

13 13 13 13 13 9:07.18 9:12.09 9:15.65 14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73 

И я хотел бы, чтобы это было разделено так ( обратите внимание на расположение запятых », ):

 13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

Приведенные выше данные довольно регулярны в том, что двузначные целые числа находятся в диапазоне [13,19], но диапазон, который я должен ожидать, – [10,99].

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

4 Solutions collect form web for “Как я могу разбить эту строку?”

Упрощенное утверждение (?=...) может решить следующее:

 >>> a = """13 13 13 13 13 9:07.18 9:12.09 9:15.65 14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73""" >>> print(re.sub("(\d{2}) (?=\d{2}( |$))","\g<1>, ", a)) 13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

Итак, reg exp. вам нужно (\d{2}) (?=\d{2}( |$)) что означает:

  1. (\d{2}) => Сохранить 2 числа в группе 1 и сопоставить дополнительное пространство.
  2. (?=\d{2}( |$)) => сопоставить 2 числа и 1 пробел или EOL, но не потреблять их.

Ключевым моментом здесь является то, что, не потребляя вторую согласованную группу, она будет обработана снова в следующий раз, когда применяется подфункция. Наконец, \g<1>, заменит 1. теми же числами и дополнительными,.

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

 sed ":a;s/\([^,]\)\(\s[0-9]\{2\}\s\)/\1,\2/;ta" 

или

 sed -E ":a;s/([^,])(\s[0-9]{2}\s)/\1,\2/;ta" 
  • начать цикл
    • искать
      • что-то другое, чем, важно для петли позже
      • пробел, две цифры и пробел
    • заменить на запятую, запятую и остальные
  • если это что-то заменит

Выход (точно так же, как желаемый выход):

 13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

Если вы хотите использовать нереджекс-решение Python, вы можете сделать следующее:

 s = """\ 13 13 13 13 13 9:07.18 9:12.09 9:15.65 14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73""" res="" for line in s.splitlines(): buf=line.split() for i, e in enumerate(buf[1:], 1): buf[i-1]+=", " if e.isdigit() else " " res+=''.join(buf)+"\n" >>> res 13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

В awk вы можете делать:

 awk '{n=split($0,a) for (i=2;i<=n;i++) printf "%s%s", a[i-1], a[i]~/^[[:digit:]]+$/ ? ", " : " " print a[n] }' file 13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

Добавляя к ответу VMRuiz , он выводит список для каждой строки, а не одну большую строку. Мне пришлось изменить регулярное выражение, чтобы использовать re.split вместо re.sub , и я не уверен, что это эквивалентно.

 for line in a.split('\n'): re.split('(?<=\d{2}) (?=\d{2} |$)', line) 

Редактировать: Это определенно то же самое, но немного неудобно:

 for line in re.sub('(\d{2}) (?=\d{2}( |$))', '\g<1>,', a).split('\n'): line.split(',') 
  • Как случайным образом удалить несколько строк из большого файла?
  • Редактирование атрибутов PDF с помощью sed
  • удаление расширений в подкаталогах
  • Использование grep для чтения журнала для pattern1 в файле и печати только строк, содержащих pattern1. Прекратите поиск, когда pattern2 найден в файле
  • Python - используя подпроцесс для вызова sed?
  • Удаление текста из текстового файла
  • Правильный способ избежать вызова подпроцесса в python
  • Использовать имя папки в виде столбца в текстовом файле
  • Python - лучший язык программирования в мире.