Разделить предложения по специальным символам, но сохранить все на выходе [дубликат]

Если вы используете систему модулей на стороне сервера, вам не нужно вообще использовать Babel. Для использования модулей в NodeJS убедитесь, что:

  1. Используйте версию узла, которая поддерживает флаг -experimental-modules
  2. Файлы .js должен быть переименован в .mjs

Вот и все.

Однако, но это большой, хотя ваш чистый ESK-код shinny будет работать в среде, такой как NodeJS ( при написании 9.5.0), у вас все еще будет сумасшествие транспиляции только для тестирования. Также имейте в виду, что Ecma заявила, что циклы выпуска для Javascript будут быстрее, а новые функции будут предоставляться на регулярной основе. Хотя это не будет проблемой для отдельных сред, таких как NodeJS, это несколько другое предложение для среды браузера. Понятно, что в рамках тестирования очень много предстоит сделать. Вам все равно нужно будет перераспределить для тестирования фреймворки. Я предлагаю использовать шутки.

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

131
задан Ken Kinder 26 January 2010 в 00:41
поделиться

9 ответов

>>> re.split('(\W)', 'foo/bar spam\neggs')
['foo', '/', 'bar', ' ', 'spam', '\n', 'eggs']
184
ответ дан Commodore Jaeger 24 August 2018 в 19:06
поделиться
  • 1
    Это круто. Я не знал, что re.split сделал это с группами захвата. – Laurence Gonsalves 26 January 2010 в 00:48
  • 2
    @Laurence: Ну, это задокументировано: docs.python.org/library/re.html#re.split : & quot; Разделить строку по случаям шаблона. Если в шаблоне используются скобки для скобок, тогда текст всех групп в шаблоне также возвращается как часть результирующего списка. & Quot; – Vinay Sajip 26 January 2010 в 00:54
  • 3
    Это серьезно недооценено. Я использую Python в течение 14 лет и только что нашел это. – smci 19 June 2013 в 17:33
  • 4
    Также возможно избежать специальных символов в строке , что упрощает создание регулярного выражения, которое соответствует списку строк. – Anderson Green 4 March 2014 в 06:00
  • 5
    Есть ли опция, чтобы результат группового совпадения привязывался ко всему, что находится слева (или аналогично справа) раскола? Например, можно ли это легко изменить, чтобы выход был ['foo', '/bar', ' spam', '\neggs']? – ely 9 February 2015 в 03:24

Вы также можете разделить строку с массивом строк вместо регулярного выражения, например:

def tokenizeString(aString, separators):
    #separators is an array of strings that are being used to split the the string.
    #sort separators in order of descending length
    separators.sort(key=len)
    listToReturn = []
    i = 0
    while i < len(aString):
        theSeparator = ""
        for current in separators:
            if current == aString[i:i+len(current)]:
                theSeparator = current
        if theSeparator != "":
            listToReturn += [theSeparator]
            i = i + len(theSeparator)
        else:
            if listToReturn == []:
                listToReturn = [""]
            if(listToReturn[-1] in separators):
                listToReturn += [""]
            listToReturn[-1] += aString[i]
            i += 1
    return listToReturn


print(tokenizeString(aString = "\"\"\"hi\"\"\" hello + world += (1*2+3/5) '''hi'''", separators = ["'''", '+=', '+', "/", "*", "\\'", '\\"', "-=", "-", " ", '"""', "(", ")"]))
2
ответ дан Anderson Green 24 August 2018 в 19:06
поделиться

другой пример, разделить на не-буквенно-цифровой и сохранить разделители

import re
a = "foo,bar@candy*ice%cream"
re.split('([^a-zA-Z0-9])',a)

:

['foo', ',', 'bar', '@', 'candy', '*', 'ice', '%', 'cream']

пояснение

re.split('([^a-zA-Z0-9])',a)

() <- keep the separators
[] <- match everything in between
^a-zA-Z0-9 <-except alphabets, upper/lower and numbers.
1
ответ дан anurag 24 August 2018 в 19:06
поделиться

Если вы хотите разделить строку, сохраняя разделители по регулярному выражению без захвата группы:

def finditer_with_separators(regex, s):
    matches = []
    prev_end = 0
    for match in regex.finditer(s):
        match_start = match.start()
        if (prev_end != 0 or match_start > 0) and match_start != prev_end:
            matches.append(s[prev_end:match.start()])
        matches.append(match.group())
        prev_end = match.end()
    if prev_end < len(s):
        matches.append(s[prev_end:])
    return matches

regex = re.compile(r"[\(\)]")
matches = finditer_with_separators(regex, s)

Если предположить, что регулярное выражение завернуто в группу захвата:

def split_with_separators(regex, s):
    matches = list(filter(None, regex.split(s)))
    return matches

regex = re.compile(r"([\(\)])")
matches = split_with_separators(regex, s)

Оба способа также удаляют пустые группы, которые бесполезны и раздражают в большинстве случаев.

1
ответ дан Dmitriy Sintsov 24 August 2018 в 19:06
поделиться

Если у вас есть только 1 разделитель, вы можете использовать списки:

text = 'foo,bar,baz,qux'  
sep = ','

Добавление / добавочный разделитель:

result = [x+sep for x in text.split(sep)]
#['foo,', 'bar,', 'baz,', 'qux,']
# to get rid of trailing
result[-1] = result[-1].strip(sep)
#['foo,', 'bar,', 'baz,', 'qux']

result = [sep+x for x in text.split(sep)]
#[',foo', ',bar', ',baz', ',qux']
# to get rid of trailing
result[0] = result[0].strip(sep)
#['foo', ',bar', ',baz', ',qux']

Сепаратор как собственный элемент:

result = [u for x in text.split(sep) for u in (x, sep)]
#['foo', ',', 'bar', ',', 'baz', ',', 'qux', ',']
results = result[:-1]   # to get rid of trailing
3
ответ дан Granitosaurus 24 August 2018 в 19:06
поделиться

Если вы раскалываете новую строку, используйте splitlines(True) .

>>> 'line 1\nline 2\nline without newline'.splitlines(True)
['line 1\n', 'line 2\n', 'line without newline']

(Не общее решение, но добавив это здесь, если кто-то приходит сюда, не понимая этого метод существует.)

14
ответ дан Mark Lodato 24 August 2018 в 19:06
поделиться
# This keeps all separators  in result 
##########################################################################
import re
st="%%(c+dd+e+f-1523)%%7"
sh=re.compile('[\+\-//\*\<\>\%\(\)]')

def splitStringFull(sh, st):
   ls=sh.split(st)
   lo=[]
   start=0
   for l in ls:
     if not l : continue
     k=st.find(l)
     llen=len(l)
     if k> start:
       tmp= st[start:k]
       lo.append(tmp)
       lo.append(l)
       start = k + llen
     else:
       lo.append(l)
       start =llen
   return lo
  #############################

li= splitStringFull(sh , st)
['%%(', 'c', '+', 'dd', '+', 'e', '+', 'f', '-', '1523', ')%%', '7']
2
ответ дан Moisey Oysgelt 24 August 2018 в 19:06
поделиться

Другое решение без регулярного выражения, которое хорошо работает на Python 3

# Split strings and keep separator
test_strings = ['<Hello>', 'Hi', '<Hi> <Planet>', '<', '']

def split_and_keep(s, sep):
   if not s: return [''] # consistent with string.split()

   # Find replacement character that is not used in string
   # i.e. just use the highest available character plus one
   # Note: This fails if ord(max(s)) = 0x10FFFF (ValueError)
   p=chr(ord(max(s))+1) 

   return s.replace(sep, sep+p).split(p)

for s in test_strings:
   print(split_and_keep(s, '<'))


# If the unicode limit is reached it will fail explicitly
unicode_max_char = chr(1114111)
ridiculous_string = '<Hello>'+unicode_max_char+'<World>'
print(split_and_keep(ridiculous_string, '<'))
7
ответ дан ootwch 24 August 2018 в 19:06
поделиться

Одно ленивое и простое решение

Предположим, что ваш шаблон регулярного выражения split_pattern = r'(!|\?)'

Сначала вы добавляете тот же символ, что и новый разделитель, например '[cut]'

new_string = re.sub(split_pattern, '\\1[cut]', your_string)

Затем вы разделите новый разделитель, new_string.split('[cut]')

0
ответ дан Yilei Wang 24 August 2018 в 19:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: