regex 正则表达式从字符串中提取前3个单词

2izufjch  于 2023-06-25  发布在  其他
关注(0)|答案(4)|浏览(106)

我试图替换所有的话,除了前3个字从字符串(使用textpad)。
Ex值:This is the string for testing.
我只想摘出三个字:This is the从上面的字符串中删除所有其他单词。
我计算出正则表达式来匹配3个单词
(\w+\s+){3}
,但我需要匹配除前3个单词之外的所有其他单词,并删除其他单词。有人能帮我吗?

c8ib6hqw

c8ib6hqw1#

具体如何取决于味道,但要消除除了前三个词之外的所有内容,您可以用途:

^((?:\S+\s+){2}\S+).*

其将前三个单词以及字符串的其余部分捕获到捕获组1中。对于替换字符串,使用对捕获组1的引用。在C#中,它可能看起来像:

resultString = Regex.Replace(subjectString, @"^((?:\S+\s+){2}\S+).*", "${1}", RegexOptions.Multiline);
rjjhvcjd

rjjhvcjd2#

编辑:为每个正则表达式添加了行起始锚,并添加了TextPad特定标志。
如果你想去掉前三个词,抓住剩下的,

^(?:\w+\s+){3}([^\n\r]+)$

?:将前三个单词更改为非捕获组,并捕获其后的所有内容。
这是你要找的吗我不太清楚你的问题,或者你的目标。
正如所建议的,这里是相反的。只捕获前三个单词,并丢弃其余的:

^(\w+\s+){3}(?:[^\n\r]+)$

只是移动?:从第一分组到第二分组。
至于“替换”那个捕获的组,您希望用什么替换它?要单独替换每个单词,您必须单独捕获每个单词:

^(\w+)\s+(\w+)\s+(\w+)\s+(?:[^\n\r]+)$

然后,例如,你可以用它的第一个字母大写替换每个字母:
替换为:\u$1 \u$2 \u$3
结果为This Is The
在TextPad中,替换中的小写\u意味着只更改下一个字母。大写\U会改变后面的所有内容(直到下一个大写标志)。
试试看:
http://fiddle.re/f3hgv
(按[Java]或任何相关语言。请注意,RegexPlanet不支持\u。)

xwbd5t1u

xwbd5t1u3#

从一个重复的问题开始,我将发布一个解决方案,它适用于不支持Perl扩展\s\W等的“传统”regex实现。对于那些甚至不熟悉正则表达式有不同方言(也就是不同风格)的新手,建议阅读例如。Why are there so many different regular expression dialects?
如果你有POSIX类支持,你可以使用[[:alpha:]]\w[^[:alpha:]]\W[[:space:]]\s,等等。但是,如果我们假设空白始终是一个空格,并且您想提取空格之间的前三个标记,那么您甚至不需要这样做。

[^ ]+[ ]+[^ ]+[ ]+[^ ]+

匹配由空格分隔的三个标记。(我将空格放在括号中,以使其突出,并且如果您想在令牌分隔符集中包含其他字符而不仅仅是单个常规ASCII空格,则易于扩展。例如,如果您的regex方言接受\t作为tab,或者您能够在其位置粘贴常规tab,则可以将其扩展为

[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+

在大多数shell中,可以使用ctrl+vtab来输入文本制表符,即用转义码作为前缀,通常通过按住ctrl键并键入v来键入转义码。)
要真正使用它,你可能需要

grep -Eo '[^ ]+[ ]+[^ ]+[ ]+[^ ]+' file

其中,单引号是保护正则表达式不受shell影响所必需的(双引号在这里也可以工作,但更弱,或者反斜杠正则表达式中对shell有意义的每个字符作为元字符),或者

sed -r 's/([^ ]+[ ]+[^ ]+[ ]+[^ ]+).*/\1/' file

仅用捕获的表达式替换每一行(圆括号构成了一个捕获组,您可以在sed中的s命令的替换部分使用\1引用它)。-r选项选择了一个比基本的传统sed更有特色的正则表达式方言;如果您sed没有,请尝试使用-E,或者在每个括号和加号前加上一个反斜杠。
由于正则表达式的工作方式,* 前 * 三个很容易,因为正则表达式引擎总是返回行上第一个可能的匹配。如果你想要从 * 秒开始的三个标记,你必须放入一个skip表达式。修改上面的sed脚本,这将是

sed -r 's/[^ ]+[ ]+([^ ]+[ ]+[^ ]+[ ]+[^ ]+).*/\1/'

你会注意到在捕获之前我是如何放入token+non-token组的。(这对于grep -o来说是不可能的,除非您有grep -P,在这种情况下,您可以使用Perl扩展的全部内容。
如果你的正则表达式方言支持 {m,n} 重复,你当然可以重构正则表达式来使用它。如果您需要大量的重复,它当然更易读,更易维护。只要确保不要在分解反向引用顺序的地方添加括号(第一个左括号创建第一个组\1,第二个\2,等等)。

sed -r 's/([^ ]+([ ]+[^ ]+){2}).*/\1/' file

请注意,第二个带括号的组对于指定{2}重复的范围是多么必要(我们希望重复的不仅仅是紧挨左花括号之前的单个字符)。OP的尝试有一个错误,重复被指定在最后一个括号之外;然后,反向引用\1(或者在你的方言中称为它的任何东西- TextMate似乎使用$1,就像Perl一样)将引用捕获括号的最后一个匹配,因为重复不是捕获的一部分,在捕获括号之外。

ztmd8pv5

ztmd8pv54#

使用,在我的情况下没有\s,因为\s包含\v,这会导致仅通过Regex提取单词的问题。

((?:\S+[\t\r\f\ ]*){1,3}).*
enter code here

参见以下示例:https://regex101.com/r/SmVjWY/1

相关问题