正则表达式:用相同数量的另一个字符替换任意数量的空白


0

我想要做的是获取一个格式很像目录的列表并用点替换左右文本之间的空格(单个空格字符,而不是制表符),只保留两个最外面的空白字符。

具体来说,我想采取这样的列表:

foo        url1
foobar     url2
foo bar    url3

并将其转换为:

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

我正在使用Eclipse IDE来编辑我的文本。我不熟悉不同的正则表达式引擎,但我猜它使用Jakarta Regexp或java.util.regex(我在维基百科上查找)。

我可以使用“ ” 在“ 查找”字段中捕获空白字符( +),但我不知道如何将它们转换为“ 替换为”字段中相同数量的点。

我做了一些谷歌搜索并遇到了这个问题(这是我学习“ ( +)”语法的地方)。听起来它可能是相同的,或类似的问题。但我要么找不到答案,要么就是不明白给出的答案。


任何空白区域或只是空格?你的表达似乎只是关于空格。那么为什么不用你喜欢的任何角色替换空间呢?
粘性

因为他们不想改变标题中的空格; 例如,“foo bar”→“foo.bar”。此外,他们不想将“foo url”改为“foo ........ url”; 他们想要“foo␣......␣url”(保留第一个和最后一个空格)。
斯科特

@Scott正确。
AntumDeluge

这听起来像是之前提出的一个问题,所以很可能已经在这里或Unix和Linux Stack Exchange上得到了解答。但我现在不记得答案了。当我有更多时间时,我会试着回到这个时间,但是,在那之前,我建议你更难以搜索我们的网站。提示:Stack Exchange有自己的搜索引擎,但有时你会使用Google获得更好的结果并说  site:superuser.com 或  site:unix.stackexchange.com
斯科特

我做了一个简短的搜索(大约15分钟),我没有找到任何完全匹配,虽然使用sed替换所有出现的匹配数量的替换字符串匹配行中的替换字符是接近。由于没有人将您的问题标记为副本,并且您到目前为止只得到了一个答案,我自己发明了三个答案(第一个与我链接的问题中的一个非常相似)。我希望你能访问sed
斯科特

Answers:


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))前面的空间是强制性的,那么相反 (?<!\S)的空间可以选择空间,并且在第一个空格被点替换后就是这种情况。
托托

好吧,我还是不明白。:-(⁠
Scott

0

问题明确指出标题将包含空格。为了安全起见,我假设标题可能包含点(句点); 例如,“3.14159的历史”或“博士 杜利特尔的发现“。我的答案假设某些字符永远不会出现在目录中; 具体来说,他们认为是@。如果你@在你的餐桌,与从未出现一些字符替换它(例如#^_|,等)。如果你真的使用每个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个连续字符组成的字符串,这些字符可以是空格,也可以@是空格,并且只用前面的空格替换它。替换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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.