Regex: замініть довільну кількість пробілів на однакову кількість іншого символу


0

Що я намагаюся зробити, це взяти список, форматований так, як зміст і замінити пробіли (символи пробілу, а не вкладки) між текстами зліва та праворуч крапками, зберігаючи лише два зовнішніх символи пробілу.

Отже конкретно, я хочу взяти такий список:

foo        url1
foobar     url2
foo bar    url3

І перетворіть це на це:

foo ...... url1
foobar ... url2
foo bar .. url3

Я використовую IDE Eclipse для редагування тексту. Я не знайомий з різними двигунами регексу, але я здогадуюсь, що він використовує або Jakarta Regexp, або java.util.regex (який я шукав у Вікіпедії).

Я можу зафіксувати символи пробілів у полі Find, використовуючи " ( +)", але я не знаю, як перетворити їх у однакову кількість точок у полі Замінити на .

Я зробив декілька гуглів та натрапив на це питання (саме там я вивчив ( +)синтаксис " "). Здається, це може бути те саме, або подібне до мого питання. Але я або не знайшов своєї відповіді, або просто не зрозумів наданих відповідей.


Будь-який пробіл чи просто пробіли? Здається, ваше вираження стосується лише пробілів. Тоді чому б просто не замінити простір будь-яким персонажем, який вам подобається?
липкий шматочок

Тому що вони не хочуть змінювати пробіли в заголовку; наприклад, "foo bar" → "foo.bar". Крім того, вони не хочуть змінювати "foo url" на "foo ........ url"; вони хочуть "foo␣ ...... ␣url" (зберігаючи перший і останній пробіл).
Скотт

@Scott Правильно.
AntumDeluge

Це звучить як питання, яке виникало раніше, і так цілком можливо, на нього вже відповіли тут або на Unix & Linux Stack Exchange . Але я зараз не пам’ятаю відповіді. Я спробую повернутися до цього пізніше, коли у мене буде більше часу, але до цього часу я пропоную вам пошукати наш сайт трохи важче. Підказка: Біржа стеків має власну пошукову систему, але іноді ви отримуєте кращі результати, використовуючи Google і говорячи  site:superuser.com або  site:unix.stackexchange.com.
Скотт

Я здійснив короткий пошук (близько 15 хвилин), і не знайшов точних збігів, хоча використання sed для заміни всіх подій на початку на відповідне число рядків заміни та Замінити символи в збігається рядку близько. Оскільки ніхто не позначав ваше запитання як дублікат, а ви досі отримали лише одну відповідь, я сам винайшов три відповіді (перший дуже схожий на один із запитань, з якими я пов’язаний). Сподіваюся, у вас є доступ sed.
Скотт

Відповіді:


1

Це можна зробити за допомогою Notepad ++

  • Ctrl+H
  • Знайти що: (?<!\S) (?= )
  • Замінити: .
  • перевірити Загорнути
  • перевірити Регулярне вираження
  • Replace all

Пояснення:

(?<!    : Start negative lookbehind, make sure we have not
  \S    : a non-space character
)       : end lookbehind
        : a space
(?=     : start lookahead, make sure we have
        : a space
)       : en lookahead

Заміна:

.       : a dot

Результат для наведеного прикладу:

foo ...... url1
foobar ... url2
foo bar .. url3

Виглядає цікаво. У мене немає Notepad ++, тому я не можу перевірити це. Чи можете ви пояснити, чому це не замінює перший пробіл після заголовка, в результаті чого foo.......␣url1?
Скотт

@Scott: Я впевнений, що він також працює з SublimeText. Простір замінюється лише тоді, коли перед ним немає пробілу і пробілу після.
Тото

Про ... коли є простір після, а НЕ не-  простір раніше. Я пропустив подвійний негатив. Чи не могли ви просто робити звичайний огляд за пробілом, а не негативний погляд позаду для простору?
Скотт

@Scott: Ні, якщо я використовую позитивний погляд позаду (тобто (?<=\s)пробіл раніше) є обов'язковим, a contrario (?<!\S) зробить пробіл опціональним, і це так, коли перший пробіл буде замінено крапкою.
Тото

Ну, я все одно не розумію. :-( ⁠
Скотт

0

У питанні прямо вказано, що заголовки будуть містити пробіли. З метою безпеки я припускаю, що заголовки можуть містити крапки (періоди); наприклад, "Історія 3.14159" або "Dr. Відкриття Doolittle ”. Мої відповіді припускають, що є якийсь символ, який ніколи не з’явиться в змісті; конкретно, вони припускають, що це так @. Якщо у вас є @в таблиці, замініть його на який - то символ , який ніколи не з'являється (наприклад, #, ^, _, |і т.д.). Якщо ви дійсно використовуєте кожен символ ASCII, можливо, вам доведеться використовувати послідовність символів, наприклад <@>.

Три способи зробити це за допомогою sed:

Петля:

sed 's/\(.*\)\( \)/\1@\2/; :loop; s/  @/ @./; t loop; s/@//'
  • s/\(.*\)\( \)/\1@\2/знаходить останній пробіл у рядку і вставляє @перед ним.
  • :loop - це мітка, як маркер милі.
  • s/ @/ @./(тобто s/␣␣@/␣@./для неоднозначності) каже, якщо перед двома пробілами є @, замініть їх на ␣.(пробіл і крапка) і перемістіть @між ними.
  • t loopкаже, якщо вищезазначена заміна вдалася, перескочіть назад до :loopмаркера і повторіть. В іншому випадку продовжуйте
  • s/@//, що видаляє @.

Отже foo barрядок у вашій таблиці буде оброблено наступним чином:

Початкове значення: foo bar url3
s / \ (. * \) \ (\) / \ 1 @ \ 2 / foo bar @ url3
s / @ / @. / foo bar @. url3
s / @ / @. / foo bar @ .. url3
s / @ / @. / foo bar @ .. url3         (Заміна не вдається, тому не петлю)
s / @ // foo bar .. url3
Кінцевий вихід: foo bar .. url3

Перебільшені числа:

sed 's/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/; s/ [ @]\{20\}/ /; s/@/./g'
  • s/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/ дуже схожий на першу sпідкоманду в першому рішенні; він знаходить останній пробіл у рядку і вставляє @перед ним рядок з 20  символів. Насправді це повинно бути число, принаймні таке велике, як максимальна кількість точок, які вам коли-небудь знадобиться вставити в одному рядку; наприклад, 80. Управління рядком з 80  @символів було б незручно; ви можете замінити це на
    • s/\(.*\)\( \)/\1<@><@><@><@><@>\2/; s/<@>/@@@@@@@@/g який вставляє рядок з п'яти <@>послідовностей, а потім замінює кожну з них рядком з 16  @символів, в результаті чого 5 × 16 = 80  @символів.
  • s/ [ @]\{20\}/ /знаходить рядок з 20 послідовних символів, який є або пробілом, або an @, якому передує пробіл, і замінює його лише попереднім пробілом. Замініть 20цифру з попереднього кроку.
  • s/@/./gзамінює кожен залишився @крапкою.

Отже fooрядок у вашій таблиці буде оброблено наступним чином:

Initial value:                  foo        url1
s/\(.*\)\( \)/\1@@@@...@@@@\2/  foo       @@@@@@@@@@@@@@@@@@@@ url1
s/ [ @]\{20\}/ /                   _[↑↑↑↑↑↑remove↑↑↑↑↑↑]
                                foo @@@@@@ url1
s/@/./g                         foo ...... url1

Використовуйте "утримуйте простір":

sed 's/.*[^ ] /&@/; h; s/ /./g; s/\(\.*\)\./\1 /; x; G; s/@.*@//'
  • s/.*[^ ] /&@/це схоже на попередні команди; він знаходить кінець заголовка - якщо бути точним, останнє місце, де за порожнім символом йде пробіл, - і вставляє @після нього.
  • h копіює рядок у місце утримування.
  • s/ /./g замінює всі пробіли в рядку крапками.
  • s/\(\.*\)\./\1 /замінює останню крапку пробілом. (Це потрібно змінити, якщо URL-адреса може містити крапки, що, напевно, ймовірно.)
  • x обмінює простір шаблону та простір утримування.
  • Gдодає простір утримування до простору шаблону. Зараз у нас є, по суті, дві копії рядка.
  • s/@.*@// зберігає першу частину першого примірника і другу частину другого примірника, позбавляючись від матеріалу в середині.
Initial value: foo bar    url3

                      Pattern space                            Hold space
s/.*[^ ] /&@/       foo bar @   url3
h                   foo bar @   url3                        foo bar @   url3
s/ /./g             foo.bar.@...url3                        foo bar @   url3
s/\(\.*\)\./\1 /    foo.bar.@.. url3                        foo bar @   url3
x                   foo bar @   url3                        foo.bar.@.. url3
G                   foo bar @   url3 foo.bar.@.. url3       foo.bar.@.. url3
s/@.*@//            foo bar .. url3                         foo.bar.@.. url3

Final output:   foo bar .. url3
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.