Как заменить элемент между двумя разделителями в TextWrangler

Я хочу заменить фонетический символ между косыми чертами фонетической транскрипции следующим образом:

/anycharacter*ou*anycharacter/

to

/anycharacter*au*anycharacter/

Я имею в виду, что хочу заменить «ou» на «au» между любыми двумя фонетическими косыми чертами во всех случаях. Например:

<font size=+2 color=#E66C2C> jocose /dʒə'kous/</font>
    =  suj vour ver / suwj dduaf 

в

<font size=+2 color=#E66C2C> jocose /dʒə'kaus/</font>
    =  suj vour ver / suwj dduaf  
  • Текстовый файл содержит HTML-код и некоторые текстовые косые черты (например, A/B вместо A или B).
  • Строка «любой символ» может состоять из любых символов, одного или нескольких символов или без них. Например: /folou/, /houl/, /sou/, /dʒə'kousnis/...

До сих пор я использовал:

Find: \/(.*?)\bou*\b(.*?)\/\s
Replace: /\1au\2\3\4/ 

но он находит все строки между любыми /.../, включая обычные косые черты и косые черты HTLM, и при замене пропускает такие элементы, как /gou/, /tou/ и т. д. Как и в приведенном выше примере, вывод:

<font size=+2 color=#E66C2C> jocose /dʒə'kaus/</font>
    =  suj vaur ver / suwj dduaf 

Примечание: это «vour» перед заменой обычной косой черты на «vaur» не является моей целью.

Не могли бы вы подсказать мне, как решить вышеуказанную проблему? Большое спасибо.


person Niamh Doyle    schedule 04.11.2011    source источник


Ответы (1)


Простейшее выражение соответствия, которое может удовлетворить ваши потребности (совместимо с POSIX ERE):

(/[^ \t/<>]*?)ou([^ \t/<>]*?/)

разбито, это означает:

(             # Capture the following into back-reference #1
  /           #   match a literal '/'
  [^ \t<>]    #   match any character that is not a space, tab, slash, or angle bracket...
    *?        #     ...any number of times (even zero times), being reluctant
)             # end capture
ou            # match the letters 'ou'
(             # Capture the following into back-reference #2
  [^ \t/<>]   #   match any character that is not a space, tab, slash, or angle bracket...
    *?        #     ...any number of times (even zero times), being reluctant
  /           #   match a literal '/'
)             # end capture

Затем используйте выражение замены \1au\2

Это будет игнорировать текст между / символами, если между ними есть пробел, табуляция, угловые скобки (< и >) или другая косая черта (/). если есть другие символы, которые, как вы знаете, не встречаются в одном из этих выражений, добавьте их в классы символов (группы [])

В моем эмуляторе получается такой текст:

<font size=+2 color=#E66C2C> jocose /dʒə'kous/</font>
    =  suj vour ver / suwj dduaf. 
Either A/B or B/C might happen, but <b>at any time</b> C/D might also occur

...в этот текст:

<font size=+2 color=#E66C2C> jocose /dʒə'kaus/</font>
    =  suj vour ver / suwj dduaf. 
Either A/B or B/C might happen, but <b>at any time</b> C/D might also occur

Просто спросите, если есть что-то, что вы не понимаете! Если хотите, я также могу объяснить несколько проблем с тем, который вы пытались использовать раньше.

ИЗМЕНИТЬ:

Приведенное выше выражение соответствует всему набору фонетической транскрипции и полностью заменяет его, используя определенные части совпадения и заменяя другие. Следующая попытка матча начнется после текущего матча.

По этой причине, если ou может встречаться более одного раза в фонетическом выражении, разделенном /, указанное выше регулярное выражение необходимо будет запустить несколько раз. Для однократного выполнения язык или инструмент должны поддерживать как переменную длину упреждающий, так и упреждающий просмотр (совместно просмотр вокруг)

Насколько я знаю, это только .Net Regex от Microsoft и «аромат» регулярного выражения JGSoft (в таких инструментах, как EditPad Pro и RegexBuddy). POSIX (который требуется UNIX grep) не поддерживает какой-либо просмотр, а Python (который, как я ДУМАЮ использует TextWrangler) не поддерживает просмотр переменной длины. Я считаю, что это было бы невозможно без просмотра переменной длины.

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

(?<=/[^ \t/<>]*?)ou(?=[^ \t/<>]*?/)

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

au

Он работает почти так же, за исключением того, что он соответствует только ou, а затем запускает проверку (называемую утверждением нулевой ширины), чтобы убедиться, что ему непосредственно предшествует / и любое количество определенных символов, и сразу за ним следует любое количество определенных символов, а затем /.

person Code Jockey    schedule 04.11.2011
comment
Ты номер один! Работает как часы. Большое вам спасибо! Однако есть небольшая проблема: он находит и заменяет по одному экземпляру за раз. Например: /,foulinizou/ требуется заменить два раза - в первый раз возвращается /,faulinizou/. Когда я снова запускаю выражение, оно возвращает /,faulinizau/. Это не большая проблема, потому что я с удовольствием запускаю выражение несколько раз, если оно решает мою проблему. И это решает мою проблему! Большое спасибо! - person Niamh Doyle; 04.11.2011
comment
Я добавил еще одну возможность, которая, боюсь, не сработает в вашем случае из-за отсутствия поддержки функций на некоторых языках и реализации регулярных выражений. - person Code Jockey; 04.11.2011
comment
Большое спасибо за ваше обновление. Я думаю, что TextWrangler не поддерживает переменную длину, потому что он выдает ошибку поиска при запуске обновленного выражения. Ошибка гласит: Шаблон Grep: утверждение lookbehind не имеет фиксированной длины. - person Niamh Doyle; 05.11.2011