- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用此正则表达式从多行字符串中删除前导和尾随空格:
s/^\s*|\s*$//mg
在这个例子中它似乎或多或少地工作得很好:
perl -e '$_=" a \n \n b\n"; s/^\s*|\s*$//mg; print "$_\n";'
给出结果:
a
b
(没想到中间有空格的双\n变成了单\n)
但是看这个:
perl -e '$_=" a \n\n b\n"; s/^\s*|\s*$//mg; print "$_\n";'
结果:
ab
现在两个\n 都消失了,多行字符串现在是单行,这不是我想要的。如果这不是错误,我该如何避免这种行为?
最佳答案
使用 -Mre=debug
模块并深入研究细节,我找到了我认为的答案。我删除了前导空格,因为它与问题无关。除了相关部分,我删除了所有内容。两个正则表达式首先使用 RHS (5:BRANCH) 匹配第二个换行符前面的空格/换行符,然后在第二个换行符前面设置指针:
情况一:字符串a\n\n b\n
Matching REx "^\s+|\s+$" against "%n b%n"
4 <a %n > <%n b%n> | 0| 1:BRANCH(5)
4 <a %n > <%n b%n> | 1| 2:MBOL(3)
| 1| failed...
4 <a %n > <%n b%n> | 0| 5:BRANCH(9)
4 <a %n > <%n b%n> | 1| 6:PLUS(8)
| 1| POSIXD[\s] can match 2 times out of 2147483647...
6 <a %n %n > <b%n> | 2| 8:MEOL(9)
| 2| failed...
5 <a %n %n> < b%n> | 2| 8:MEOL(9)
| 2| failed...
| 1| failed...
| 0| BRANCH failed...
5 <a %n %n> < b%n> | 0| 1:BRANCH(5) <-- HERE!
5 <a %n %n> < b%n> | 1| 2:MBOL(3)
5 <a %n %n> < b%n> | 1| 3:PLUS(9)
| 1| POSIXD[\s] can match 1 times out of 2147483647...
6 <a %n %n > <b%n> | 2| 9:END(0)
Match successful!
在这种情况下,LHS (1:BRANCH) 首先失败,RHS (5:BRANCH) 失败,因此它向前移动 1 步,直到换行符之后,LHS 匹配,并删除前面的内容它:一个空间。
在换行符和 b
前面的空格之间的匹配中,当正则表达式中的“指针”向前移动到换行符前面时。
%n> < b%n>
^ \s
情况 2:字符串 a\n\n b\n
Matching REx "^\s+|\s+$" against "%n b%n"
3 <a %n> <%n b%n> | 0| 1:BRANCH(5) <-- HERE!
3 <a %n> <%n b%n> | 1| 2:MBOL(3)
3 <a %n> <%n b%n> | 1| 3:PLUS(9)
| 1| POSIXD[\s] can match 2 times out of 2147483647...
5 <a %n%n > <b%n> | 2| 9:END(0)
Match successful!
在这个字符串中,LHS(1:BRANCH)中的零宽度断言^
可以看到字符串左边的换行符,并允许匹配。在另一个字符串中,它在那里有一个空格,因此无法匹配。所以 LHS 交流发电机匹配(称为 1:BRANCH),并删除它前面的内容,即换行符和空格 \n
。
与其像Case 1那样跳过第一次尝试向前移动1步,不如直接匹配左边的换行符,右边的空格\n
:
%n> <%n b%n>
^ \s\s
TL;DR:在您的第二个字符串中,换行符可以匹配两个换行符之间的行首,因此将它们都删除。在第一个字符串中,它不能那样匹配,因为那里有一个空格,而是向前移动一步,跳过换行符并使用该换行符匹配字符串的开头。效果是换行符保留在字符串中。
如何避免这种行为?嗯,问题是你的正则表达式太松散了。 \n
可以以各种组合匹配正则表达式 ^
、$
和 \s
的所有组件。它还可以匹配字符串的中间。如果您想要安全并获得可预测的结果,请以逐行模式使用正则表达式,不要将文件拖成单个字符串。那么你就不需要多行匹配了,所有的问题都迎刃而解。
否则,避免使用多行修饰符,只需照常删除前导和尾随空格,然后在字符串内部修剪多个带空格的换行符,如 s/\n\s*\n/\n/g
.
本质上,您试图同时做太多事情。使您的正则表达式更严格,并尝试一次做一件事情。
关于regex -/m 修饰符的 perl 正则表达式意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68141141/
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!