在每个非字母数字字符之前放置转义符号

lis*_*tor 10 escaping non-alphanumeric char raku

我试图在每个非字母数字字符之前放置一个转义符号:

 > my $b = "!@#%^||" ~ "/welcome xyz:!@#\$%^&*()|:;.,?/-."
!@#%^||/welcome xyz:!@#$%^&*()|:;.,?/-.

> my $c = $b.subst(/<:!L + :!N - [./-]>/, "\\" ~ $/, :g)
\ \ \ \ \ \ \ /welcome\ xyz\ \ \ \ \ \ \ \ \ \ \ \ \ \ .\ \ /-.
Run Code Online (Sandbox Code Playgroud)

这是第一次运行代码后的结果。第二次运行代码后,结果是一长串重复匹配。如果我使用“?”,会得到类似的结果 量词。

> my $c = $b.subst(/<:!L + :!N - [./-]>/, "\\" ~ $/, :g)
\! @ # % ^ | |   : ! @ # $ % ^ & * ( ) | : ; , ?\! @ # % ^ | |   : ! @ # $ % ^ & * ( ) | : ; , ?\! @ # % ^ | |      # This is truncated long string of undesired result.
Run Code Online (Sandbox Code Playgroud)

然后我尝试用梳子替换单个字符,但出现多个错误

> $b.comb.map( {.subst(/<:!L + :!N - [./-]>/, "\\" ~ $/)} )
Use of uninitialized value element of type Any in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
  in block  at <unknown file> line 1
(\! \! \@ \# \% \^ \| / w e l c o m e \ x y z \ \: \! \@ \# \$ \% \^ \& \* \( \) \| \: . \ \, / - .)
Run Code Online (Sandbox Code Playgroud)

如果我第二次运行代码,结果会略有不同:

(\ \! \@ \# \% \^ \| / w e l c o m e \ x y z \ \: \! \@ \# \$ \% \^ \& \* \( \) \| \: . \ \, / - .)
Run Code Online (Sandbox Code Playgroud)

我也不能加入这个列表:

> $b.comb.map( { if $_.so { .subst(/<:!L + :!N - [./-]>/, "\\" ~ $/)} } ).join
Use of uninitialized value element of type Any in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
  in block  at <unknown file> line 1
  in block <unit> at <unknown file> line 1
Run Code Online (Sandbox Code Playgroud)

例程 tr/// 没有完成我试图完成的任务。

在字符串中的每个非数字字符之前放置“\”的快速方法是什么?看似如此简单却又如此困难。谢谢。

wam*_*mba 8

以下代码实际上在每个非字母数字字符之前放置了一个转义符号

my $b = '!@#%^||' ~ '/welcome xyz:!@#\\$%^&*()|:;.,?/-.';
say $b.subst: / <?before <-alnum>> /, '\\', :g
Run Code Online (Sandbox Code Playgroud)
\!\@\#\%\^\|\|\/welcome\ xyz\:\!\@\#\\\$\%\^\&\*\(\)\|\:\;\.\,\?\/\-\.
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢万巴!!!简洁明了! (3认同)

rai*_*iph 2

TL;DR将替换包含在代码块 ( { ... }) 中。

\n

$/使用时出现问题subst

\n

引用$/文档

\n
\n

设置为最后一次正则表达式匹配的结果

\n
\n

这并不总是正确的。

\n

引用并适当强调我写的一个SO答案的Rakudo部分的匹配变量的“发布” (在对你写的另一个SO Q的回复中):

\n
\n

正则表达式/语法引擎对[何时值得“发布”(更新)$/]做出保守的决定。我所说的“保守”是指引擎经常避免发布,因为它会减慢速度并且通常是不必要的。不幸的是,有时对于何时真正需要发表感到过于乐观。因此,程序员有时需要通过显式插入代码块来强制发布匹配变量来进行干预......

\n
\n

上述措辞的上下文是您之前的 Q,它不是“ta subst”的替换。我还没有阅读编译器代码来检查这个新 Q 的场景中发生了什么。

\n

然而,当我读到你的新 SO Q 时,我立即感到相当有信心,当考虑文档关于$/“设置为最后一次正则表达式匹配的结果”的措辞时,并在调用的上下文中这样subst如果传递给的替换只是一个字符串,则不会发生更新$/subst

\n
\n

要更详细地了解当您不将替换包装在代码块中时发生的情况,可以将 与包装替换但仍然“en passant”的$/代码块一起使用:say

\n
my $c = $b.subst(/<:!L + :!N - [./-]>/, "\\\\" ~ $/.&{ say $_; $_ }, :g);\n
Run Code Online (Sandbox Code Playgroud)\n

如果您运行该代码,您将看到,$/最初设置为Nil.

\n

然后,在执行该语句之后、执行下一条语句之前,该值将被更新。这就是为什么您在每个后续语句中得到不同(但仍然没有帮助!)结果的原因。也就是说,正在更新,但是如果您只是在字符串表达式中使用替换而不是将其放入代码块中,则更新为时已晚,无法正常工作。$/$/ $/

\n

subst最近使用Rakudo时的解决方案

\n

再次引用同一文档:

\n
\n

$/每个例程中都会创建一个新的 [ ]。

\n
\n

再说一次,我还没有检查编译器源代码,但有一点信心,不仅在每个.\xc2\xb9中都$/创建了一个新的RoutineBlock

\n

因此,我测试了将替换包装在代码块中,果然这意味着匹配变量“发布”($/等人的更新)确实发生

\n

所以我认为这是一种解决方案。

\n

另一种解决方案

\n
\n

在字符串中的每个非数字字符之前放置“\\”的快速方法是什么?

\n
\n
$_ = \'42!@#%^||\' ~ \'/welcome xyz:!@#$%^&*()|:;.,?/-.\'; # (No need for any `\\`)\n\n.=subst: / <-:L -:N> /, { q:!b:s \'\\$/\' }, :g;\n\n.say; # 42\\!\\@\\#\\%\\^\\|\\|\\/welcome\\ xyz\\:\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\|\\:\\;\\.\\,\\?\\/\\-\\.\n
Run Code Online (Sandbox Code Playgroud)\n

这只是不同衣服的相同解决方案。

\n

我用过Q Langq。这默认为其\'...\'参数的字符串解释。但人们可以通过使用选项来广泛控制其行为。我使用了关闭:!b解释backslashes和打开标量变量(带有印记)的解释选项。:ss$

\n

脚注

\n

\xc2\xb9 当然是模优化。也就是说,我忽略了对用户代码在语义上不可见的优化(我忽略它正是因为它在语义上不可见)。这与我在之前的 SO 答案的引用中讨论的“保守呼吁”形成鲜明对比,我的意思是类似于 WONTFIX 的东西

\n