繁体   English   中英

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

[英]Place an escape sign before every non-alphanumeric characters

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

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

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

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

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

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

> $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 \ \: \! \@ \# \$ \% \^ \& \* \( \) \| \: . \ \, / - .)

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

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

我也不能加入这个列表:

> $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

例程 tr/// 没有做我试图完成的事情。

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

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

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

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

$/subst一起使用时出现问题

引用$/ doc

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

这并不总是正确的。

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

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

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

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


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

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

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

然后,执行该语句之后,但执行一条语句之前, $/值被更新。 这就是为什么您会在每个后续语句中得到不同的(但仍然没有帮助!)结果。 也就是说, $/正在更新,但是如果您只是在字符串表达式中使用$/来进行替换而不是将其放在代码块中,那么更新就来不及了

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

再次引用同一个文档:

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

同样,我还没有检查编译器源代码,但我有点确信,新的$/不仅在每个Routine中,而且在每个Block中创建。¹

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

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

另一种解决方案

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

$_ = '42!@#%^||' ~ '/welcome xyz:!@#$%^&*()|:;.,?/-.'; # (No need for any `\`)

.=subst: / <-:L -:N> /, { q:!b:s '\$/' }, :g;

.say; # 42\!\@\#\%\^\|\|\/welcome\ xyz\:\!\@\#\$\%\^\&\*\(\)\|\:\;\.\,\?\/\-\.

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

我用过Q Langq 这默认为'...'字符串,类似于对其参数的解释。 但是可以通过使用选项来广泛地控制其行为。 我已经使用:!b选项关闭解释b反斜杠,并使用:s打开解释s标量变量(使用$ sigil)

脚注

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

如果 OP 已经考虑过以下内容,我们深表歉意:

如果您尝试在 Raku 中使用反斜杠转义非 alnum 字符的唯一原因是将结果放入变量中,然后通过 Raku 正则表达式进行测试,那么在您的字符串变量上调用.raku通常会有所帮助(即它会让您参与- 的方式那里):

~~$ echo '!@#%^||/welcome xyz:!@#\$%^&*()|:;.,?/-.' | raku -ne '.raku.put'

回报:

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

查看上面的结果,您会看到中间级别的反斜杠转义,反斜杠保护$@%&\字符。

您可以从结果字符串中删除周围的双引号,如下所示:

~$ echo '!@#%^||/welcome xyz:!@#\$%^&*()|:;.,?/-.' | raku -ne '.raku.comb(/\" <(.+)> \"/).put'
!\@#\%^||/welcome xyz:!\@#\\\$\%^\&*()|:;.,?/-.

...或者稍微异想天开的:

~$ echo '!@#%^||/welcome xyz:!@#\$%^&*()|:;.,?/-.' | raku -ne '.raku.chop.flip.chop.flip.put'
!\@#\%^||/welcome xyz:!\@#\\\$\%^\&*()|:;.,?/-.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM