正则做不到这个是吧?

2018-08-03 12:09:46 +08:00
 helloiac

匹配字符串: <sometag>一些任意不定长的文字,但不包括 AT 符号和小于号</sometag>

一步将其替换为: <sometag>一 @些 @任 @意 @不 @定 @长 @的 @文 @字 @,@但 @不 @包 @括 @A@T@符 @号 @和 @小 @于 @号</sometag>

也就是在 tag 内部的任意两个字符之间插入 @ 。

我想了下应该是做不到的,请大家帮确认下。

2900 次点击
所在节点    问与答
22 条回复
thedog
2018-08-03 12:31:13 +08:00
当成一个列表,join 一下?不明白为什么要用正则
jayx
2018-08-03 12:33:43 +08:00
python 零宽断言匹配,然后 join()方法插入
CEBBCAT
2018-08-03 12:49:37 +08:00
正则把 sometag 匹配出来,别的事交给我 C 来做
dreasky
2018-08-03 13:11:51 +08:00
re.sub(r'(.)', r'@\1', r'一些任意不定长的文字,但不包括 AT 符号和小于号')
'@一 @些 @任 @意 @不 @定 @长 @的 @文 @字 @,@但 @不 @包 @括 @ @A@T@ @符 @号 @和 @小 @于 @号'

中文需要 python3,剩下的问题很简单
rabbbit
2018-08-03 13:23:41 +08:00
硬写成一行倒是可以 js
text = '<sometag>一些任意不定长的文字,但不包括 AT 符号和小于号</sometag>';
text.replace(/(?<=<sometag>)(.*)(?=<\/sometag>)/, (str) => {return str.split('').filter(function(i) { return i.trim() !== '' ? true: false}).join('@')});
// "<sometag>一 @些 @任 @意 @不 @定 @长 @的 @文 @字 @,@但 @不 @包 @括 @A@T@符 @号 @和 @小 @于 @号</sometag>"
rabbbit
2018-08-03 13:25:45 +08:00
更正
text.replace(/(?<=<sometag>)(.*)(?=<\/sometag>)/, (str) => {return str.split('').filter((i) => { return i.trim() !== ''}).join('@')});
helloiac
2018-08-03 13:40:27 +08:00
@dreasky 谢谢。因为待匹配文本是不确定的,且有 tag 包裹这个 context 限定,所以恐怕这个方案不可行。
ragnaroks
2018-08-03 13:42:00 +08:00
有个文本处理问题,他想到用正则来解决,现在他有两个问题了
helloiac
2018-08-03 13:42:15 +08:00
@thedog 谢谢,APPEND 了信息,没有类似 join 的函数可用,且效率太低。
ragnaroks
2018-08-03 13:43:22 +08:00
如果是每个字符后加 at 的话,我的想法是创建个 2 倍字符数的数组,遍历进去..
helloiac
2018-08-03 13:44:15 +08:00
@CEBBCAT 是不是正则匹配出来,暂存到变量,更改后再 replace 回去呀?
helloiac
2018-08-03 13:45:58 +08:00
@rabbbit 谢谢具体方案,用比较高级的语言的话这个方案挺好的,不过我用的是 shell,sed 也不支持零宽断言。
yyfearth
2018-08-03 13:51:45 +08:00
@helloiac 正则一次找不到 但是两次应该可以做到
先把 tag 里面的内容抓出来 然后替换里面的内容 每个字后面中间加 at (除了第一个字 每个字去买加 或者 除了最后一个 每个后面加)

@rabbbit 都用上 箭头了 为啥还要用 return 另外可以不用 filter
text.replace(/(?<=<sometag>)(.*)(?=<\/sometag>)/, str => str.split(/\s*/).join('@'))

另外这个用到了最新的 ES RegExg 的功能 "?<=" 其实不用也可以
text.replace(/(<sometag>)(.*)(?=<\/sometag>)/, (a, b, str) => b + str.split(/\s*/).join('@'))
JmmBite
2018-08-03 13:58:19 +08:00
```ruby
'<tag>一些任意不定长的文字,但不包括 AT 符号和小于号</tag>'.gsub(/(?<!>)([^\@\>\<\s])/, " @\\1")

=> "<tag>一 @些 @任 @意 @不 @定 @长 @的 @文 @字 @, @但 @不 @包 @括 @A @T @符 @号 @和 @小 @于 @号</tag>"
```
FanWall
2018-08-03 14:10:15 +08:00
正则很容易做到,但如果不支持环视就无法一句搞定。
helloiac
2018-08-03 15:17:56 +08:00
@JmmBite 在 irb 运行了一下,结果跟你的不一样。

irb(main):004:0> '<tag>abcdefg</tag>'.gsub(/(?<!>)([^\@\>\<\s])/, " @\\1")
=> "< @t @a @g>a @b @c @d @e @f @g< @/ @t @a @g>"
CEBBCAT
2018-08-03 16:25:27 +08:00
@helloiac #11 输入输出流分开,加了'@'的文本直接写到另一个文件里去
goofool
2018-08-03 18:37:03 +08:00
瞎写
sed """ /<.*>/{h; s/\(<[^\/]*>\).*/\1/p;g;s/<.*>\(.*\)<\/.*>/\1/;s/\(.\)/\1@/g; s/@$//p;g;s/.*\(<\/.*>\)/\1/p;d;}; p """ test.txt
rabbbit
2018-08-04 02:46:06 +08:00
@yyfearth
你记忆力真好啊,我就记不住这么多用法细节
hundan
2018-08-04 12:45:02 +08:00
@FanWall 怎么做呢,想了想感觉用环视也做不出

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/476548

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX