提问人:batteredveg 提问时间:10/31/2023 最后编辑:InSyncbatteredveg 更新时间:10/31/2023 访问量:96
正则表达式:在特定单词后替换空格
Regex: substitute spaces after specific word
问:
我正在尝试(但失败了)编写一个正则表达式 (PCRE2),它将在特定单词(即 •VAN•、•VON• 或 •DE•)的第一个实例之后用破折号 (-) 替换每个空格,该单词本身必须被空格包围。
例如:
HENRIETTA VON DER GRAAF
CAROLINE VAN OOSTEN DE WINKEL
MARC DE VRIES VAN JONG
ANNEKA VANHOVEN BAKKER
JOHN WILKINSON SMITH
可以翻译为:
HENRIETTA VON-DER-GRAAF
CAROLINE VAN-OOSTEN-DE-WINKEL
MARC DE-VRIES-VAN-JONG
ANNEKA VANHOVEN BAKKER (NB: Does not match VAN as not surrounded by spaces)
JOHN WILKINSON SMITH (NB: No substitution here as pattern not matched)
这是我所知道的,但它并没有替换比赛后的所有空格:
\b( VON| VAN| DE)+\s
https://regex101.com/r/s6BC1y/1
任何建议,非常感谢!
答:
0赞
Gilles Quénot
10/31/2023
#1
使用 Perl:
perl -anE '
if (/\b(?:VON|VAN|DE)\b/) {
@a = split /\s+/;
say $a[0], " ", join "_", @a[1..$#a]
} else {
print;
}
' file
HENRIETTA VON_DER_GRAAF
CAROLINE VAN_OOSTEN_DE_WINKEL
MARC DE_VRIES_VAN_JONG
ANNEKA VANHOVEN BAKKER
JOHN SMITH
3赞
InSync
10/31/2023
#2
这可以通过以下方式完成:\G
\K
(?: # Match either
(?<!\S) # but only if it is not preceded by a whitespace,
(?:VON|VAN|DE) # 'VON', 'VAN' or 'DE'
| # or
\G(?!\A) # the end of the last match
\S+ # then a sequence of non-whitespace characters.
) #
\K\x20 # Forfeit everything we just match, then match a space.
由于 PCRE2 中缺乏对非固定宽度后视的支持,我们无法执行以下操作,这可以说更容易理解:
(?<= # Match a position preceded by
(?:VON|VAN|DE) # either of the three words
(?:\x20\S+)* # then 0 or more (space + word),
) #
\x20 # and a space at that position.
\G
匹配最后一个匹配项末尾的位置或整个字符串的开头位置。多亏了 ,后一个备选方案只有在我们匹配第一个备选方案时才会匹配: 。(?!\A)
(?<!\S)(?:VON|VAN|DE)
视觉解释:
MARC DE VRIES VAN JONG
^ Start matching `(?<!\S)(?:VON|VAN|DE)`
MARC DE VRIES VAN JONG
^ ...then `\x20`.
MARC DE VRIES VAN JONG
^ `(?<!\S)(?:VON|VAN|DE)` doesn't match here; switch to `\S+`
MARC DE VRIES VAN JONG
^ `\x20` is matched.
MARC DE VRIES VAN JONG
^ Back to step 1.
MARC DE VRIES VAN JONG
^ Back to step 3.
2赞
Nick
10/31/2023
#3
您可以使用此正则表达式实现所需的结果:
^(.*? (?:VAN|VON|DE)) |((?<!^)\G\w+)
这与以下任一匹配:
^(.*? (?:VAN|VON|DE))
:行首后的一些最小字符数,后跟一个空格,以及 或 中的一个,全部捕获在第 1 组中,然后是一个空格;或VON
VAN
DE
((?<!^)\G\w+)
:从上次成功匹配的末尾开始(但不从字符串的开头开始,通常允许)开始的一定数量的单词字符,在第 2 组中捕获,然后是一个空格\G
然后,您可以将匹配项替换为(只有一个或将包含任何内容)。$1$2-
$1
$2
regex101 上的正则表达式演示
请注意,正则表达式可以简化为丢弃匹配的第一部分,只匹配单词后面的空格:\K
^.*? (?:VAN|VON|DE)\K |(?<!^)\G\w+\K
那么替换就是简单的.-
regex101 上的正则表达式演示
2赞
Richard
10/31/2023
#4
您可以在没有正则表达式的情况下进行转换。
data have;
input text $CHAR50.;
datalines;
HENRIETTA VON DER GRAAF
CAROLINE VAN OOSTEN DE WINKEL
MARC DE VRIES VAN JONG
ANNEKA VANHOVEN BAKKER
JOHN WILKINSON SMITH
;
data want;
set have;
p = prxmatch('m/\b(VAN|VON|DE)( )/',text);
if 0 < p < length(text) then
substr(text,p+1) = translate(substr(trim(text),p+1),'-',' ');
run;
评论
0赞
Therkel
11/1/2023
“你可以在没有正则表达式的情况下进行转换”,使用让我感到困惑。prxmatch
评论
-
OOSTEN
VRIES
+