AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 781265
Accepted
Jonathan Komar
Jonathan Komar
Asked: 2024-08-02 19:59:04 +0800 CST2024-08-02 19:59:04 +0800 CST 2024-08-02 19:59:04 +0800 CST

为什么这个 Perl Regex 单行代码不遵守 \U 转义序列?

  • 772

为什么此 Perl Regex 单行代码没有使用修饰符使完整结果大写\U?

我预计MY_NICE_WORD。

$ perl -pe 's/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/\U$1_$2\E/g' <(echo 'myNiceWord HTTPHeader')
my_Nice_Word HTTP_Header

根据文档,

The following escape sequences are available in constructs that interpolate, but not in transliterations.

           \l          lowercase next character only
           \u          titlecase (not uppercase!) next character only
           \L          lowercase all characters till \E or end of string
           \U          uppercase all characters till \E or end of string
           \F          foldcase all characters till \E or end of string
           \Q          quote (disable) pattern metacharacters till \E or
                       end of string
           \E          end either case modification or quoted section
                       (whichever was last seen)

来源:man --pager 'less -p "The following escape sequences are available in constructs that interpolate, but not in transliterations."' perlop

替换文本不是在插值上下文中吗?

工作示例

根据我的理解,遵循文档后我可以提供这个工作示例:

$ perl -pe 's/(hello)/\U$1\E/g' <(echo hello)
HELLO

正则表达式来自https://stackoverflow.com/a/1176023/1236128

-> 这涵盖的重要情况:HTTPHeader 不会变成 h_t_t_p_header,而是HTTP_Header(或大写的 HTTP_HEADER)

regular-expression
  • 3 3 个回答
  • 72 Views

3 个回答

  • Voted
  1. Best Answer
    Chris Davies
    2024-08-02T21:12:51+08:002024-08-02T21:12:51+08:00

    您正在使用前瞻((?=…))和后瞻((<?=…))断言,没有任何内容可以匹配和替换。

    我认为这就是您想要实现的目标,即在每个大写字母前面添加下划线,然后将整个字符串大写:

    perl -pe 's/([a-z]*)([A-Z][a-z]+)/\U$1_$2/g' <<<'myWord'
    MY_WORD
    
    perl -pe 's/([a-z]*)([A-Z][a-z]+)/\U$1_$2/g' <<<'myNiceWord'
    MY_NICE_WORD
    
    perl -pe 's/([a-z]*)([A-Z][a-z]+)/\U$1_$2/g' <<<'myReallyNiceWord'
    MY_REALLY_NICE_WORD
    

    但,

    perl -pe 's/([a-z]*)([A-Z][a-z]+)/\U$1_$2/g' <<<'ReallyNiceWord'
    _REALLY_NICE_WORD
    

    所以也许

    perl -pe 's/([a-z]*)([A-Z][a-z]+)/\U$1_$2/g; s/^_//' <<<'ReallyNiceWord'
    REALLY_NICE_WORD
    

    如果这就是您要去的地方,那么更容易将“单词”按大写字母拆分,用 连接各个部分_,然后将结果大写:

    perl -pe '$_ = uc join("_", split(/(?=[A-Z])/) )' <<<'myReallyNiceWord'
    MY_REALLY_NICE_WORD
    
    • 3
  2. Ole Tange
    2024-08-02T21:11:30+08:002024-08-02T21:11:30+08:00

    我发现两个问题:您使用了零宽度断言。我认为无法一次性完成此操作。

    这对你有用吗:

    echo "unaffected Unaffected myNiceWord" |
      perl -pe 's/([a-z])([A-Z])/$1_$2/g; s/([a-zA-Z]*_[A-Z][a-z]*)/\U$1\E/g'
    

    它在 myFWord 上失败了。

    • 1
  3. Jonathan Komar
    2024-08-04T02:10:18+08:002024-08-04T02:10:18+08:00

    这个答案解决了 OP 问题,即当使用 0 宽度匹配时,使结果大写/无法在组捕获上使用 \U(并继续使用相同的正则表达式):

    答案是你不能在使用 $1 和 $2的零宽度(?<=...) 或 (?=...) 的组匹配器上使用 \U \E,因为它们不是捕获组,而是查看运算符 (感谢 Stéphane Chazelas)

    解决此限制的一种方法是在不改变原始表达式的情况下对结果进行后处理,如下所示:

    使用 Perl 特殊变量$_来对应用于字符串的表达式的输出进行处理:$_ = uc($_)其中uc是 Perl 中的内置大写函数,将结果转换为大写。

    perl -pe 's/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/\U$1_$2\E/g; $_ = uc($_)' <(echo 'myNiceWord HTTPHeader')
    MY_NICE_WORD HTTP_HEADER
    

    附言:muru 的评论回答了为什么 \U 不起作用的问题,这也是我写这篇回答的动机。谢谢。

    您的所有匹配项不是都是零宽度吗? $1 和 $2 只是空字符串。

    • 0

相关问题

  • 如何在匹配后删除几个字符?

  • 使用 POSIX 工具正确处理带有 BOM 的 Unicode 文件

  • 为什么正则表达式与 sed 命令的输入不匹配 [重复]

  • 使用特殊字符转换密码以与期望脚本一起使用

  • 更少:使用 AND 的多个过滤条件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve