Я изучаю тайну regexp. Я устал, поэтому мне может не хватать что-то очевидное - но я не вижу причин для этого.Регулярное выражение mystery
В приведенных ниже примерах я использую perl - но я впервые увидел это в VIM, , поэтому я предполагаю, что это нечто, связанное с более чем одним регулярным выражением.
Предположим, что мы имеем на данный файл:
$ cat data
1 =2 3 =4
5 =6 7 =8
Мы можем затем удалить пробелы в передней части «=» с ...
$ cat data | perl -ne 's,(.)\s+=(.),\1=\2,g; print;'
1=2 3=4
5=6 7=8
Обратите внимание, что в каждой строке, все экземпляры матча заменяются; мы использовали модификатор/g search, который не останавливается при первой замене, и вместо этого заменяется до конца строки.
Например, было удалено пространство перед «= 2» и пространство перед ; «= 4»; в той же строке.
Почему бы не использовать более простые конструкции типа 's, =, =, g'? Ну, мы были подготовка к более сложных сценариев ... где правая из заданий цитируются строки, и может быть либо одинарные или двойные кавычки:
$ cat data2
1 ="2" 3 ='4 ='
5 ='6' 7 ="8"
Чтобы сделать ту же работу (удалить пробел перед знаком равенства), мы должны быть осторожными, поскольку строки могут содержать равные знака - так мы отмечаем первую цитату мы видим, и искать его через обратные ссылки:
$ cat data2 | perl -ne 's,(.)\s+=(.)([^\2]*)\2,\1=\2\3\2,g; print;'
1="2" 3='4 ='
5='6' 7="8"
Мы использовал обратную ссылку \ 2 для поиска чего-либо, что не является той же цитатой, что и первая, которую мы видели в любое время ([^ \ 2] *). Затем мы выполнили поиск самой оригинальной цитаты (\ 2). Если найдено, , мы использовали обратные ссылки для ссылки на согласованные детали в замене цели .
Теперь посмотрите на это:
$ cat data3
posAndWidth ="40:5 =" height ="1"
posAndWidth ="-1:8 ='" textAlignment ="Right"
То, что мы хотим здесь, чтобы уронить последний пробел, который существует перед тем все экземпляры «=» в каждой строке. Как и раньше, мы не можем использовать простой 's, = ", =", g', потому что сами строки могут содержать знак .
Таким образом, мы по той же схеме, как мы делали выше, и использовать обратные ссылки:
$ cat data3 | perl -ne "s,(\w+)(\s*) =(['\"])([^\3]*)\3,\1\2=\3\4\3,g; print;"
posAndWidth="40:5 =" height ="1"
posAndWidth="-1:8 ='" textAlignment ="Right"
Он работает ... но только на первый матч линии! Пространство, следующее за «textAlignment», не было удалено, и ни один из них не был («высота»).
В основном, это, кажется, что/г не работает больше: под управлением той же команду заменить без/г производит точно такой же вывод:
$ cat data3 | perl -ne "s,(\w+)(\s*) =(['\"])([^\3]*)\3,\1\2=\3\4\3,; print;"
posAndWidth="40:5 =" height ="1"
posAndWidth="-1:8 ='" textAlignment ="Right"
Оказывается, что в этом регулярном выражении, то/г игнорируется , Любые идеи, почему?
Разве это не лечащий все между первой цитаты и последней цитаты в кавычках? – Nick
Часть [^ \ 3] * не может идти за пределами закрывающей цитаты, не так ли? – ttsiodras
с вашим perl cmd, я получил другой результат 'posAndWidth =" 40: 5 = "' пробел между '5' и' = 'ушел. – Kent