给定如下所示的字符串,请通过正则表达式删除所有前导和尾随的标点符号:
String a ="!?Don't.;, .:delete !the@ $actual string%";
String b ="Hyphenated-words, too!";
我知道正则表达式[ P {Alnum}]会以所有非字母数字字符为目标,但是我怎么只以前导和尾随标点为目标,所以我得到了...
a ="Don't delete the actual string";
b ="Hyphenated-words too";
... 代替:
a ="Dont delete the actual string";
b ="Hyphenated words too";
我只需要正则表达式; 不是删除标点符号的实际代码。
当您说"前导和尾随"时,这是否意味着结果应为Dont.;, .:delete !the@ $actual string? 例如,@的"前导"或"尾随"是什么,不适用于Dont中的? 而且,顺便说一句,要求使用正则表达式就是要求代码。 不要那样做。
@RealSkeptic我指的是字符串中每个单词的"前导" /"尾随"标点,而不必是字符串本身。 我没有明确指出我正在使用扫描仪定界符(这就是为什么我只需要正则表达式而不是整个代码本身的原因)。 至于您的最后评论,我不知道要求正则表达式就是要求代码。 我事先道歉
您想得到什么结果a ="不删除实际字符串"; b ="连字符的单词也"; 或这="不删除实际字符串";或者 b ="带连字符的单词";
@ J.Adder根据slns的评论,我已经更新了答案,现在使用\p{Punct}。
您要匹配与a)空格字符或b)开头或结尾相邻的标点符号。
您的模式前面加上(?<=^|\s)正向后看,或者
您的模式,后跟(?=\s|$)正向
为了缩短模式,我们可以改写一些措辞,以使我们的标点符号必须要么a)之前没有空白的字符,要么b)后面没有空白的字符。
您的模式前面加上(?否定性回溯,或者
您的模式,后跟(?!\S)负前瞻
最后一点,您应该使用\p{Punct}而不是[\P{Alnum}]来匹配标点符号。有关详细信息,请参见sln的评论。
这是一个示例用法:
String a ="!?Don't.;, .:delete !the@ $actual string%";
String b ="Hyphenated-words, too!";
String regex ="(?:(?
System.out.println(a.replaceAll(regex,""));
System.out.println(b.replaceAll(regex,""));
输出:
Don't delete the actual string
Hyphenated-words too
这仍然是一件小事,例如"连字号"也是如此!我相信你能做到
@YCF_L输入"连字符---单词!"所需的输出是什么?我的理解是" ---"不是单词的前导或结尾,而是单词的中间,因此应保持不变。还考虑" Mac-Dougal"。请做得更好,解释您想要什么。
啊,好吧,这是我的坏事,您好,我的投票给我带来了好运;)
这是一个不完整的解决方案。 \P{Alnum}也覆盖所有空白,从而有效地去除了所有格式和其他标点符号不完整的Unicode代码点。如果要使用此方法,请至少排除空格(?:(?
@sln好点。我一直以OP的假设为前提,他想使用[\P{Alnum}],但经过仔细检查,这是一个可怕的假设。
punct和alnum(ctrl除外)之后可能剩余的很少。
也可以通过使用空白边界来利用它。
找:
原始(?
字符串"(?
替换"$1"
讲解
(?
(?: # Cluster
\p{punct}* # Optional punct
( # (1 start), words to be written back
\p{alnum}+ # Required, start with alnum
(?: \p{punct}? \p{alnum} )* # Optional punct + alnum
) # (1 end)
\p{punct}* # Optional punct
| # or,
\p{punct}+ # Required punct
) # End Cluster
(?! \S ) # Whitespace boundary
之前瞄准
!?Don't.;, .:delete !the@ ()*& $actual string%
Hyphenated-words, a)
更换后目标
Don't delete the actual string
Hyphenated-words a
注意:由于OP希望将正则表达式用作"扫描仪分隔符",因此他将无法直接利用涉及$1或类似内容的任何答案。
您可以使用以下正则表达式:
(?:[^\w\s]*)(\S*?)[^\w\s]*(?=\s|$)
并由
$ 1
对于您的样本输入,输出为:
Don't delete the actual string
Hyphenated-words too
注意:我使用过\w,但是如果需要更精确的字母数字定义,请用\p{Alnum}替换两个\w。
您可以使用^和$。 ^匹配字符串的开头,$结尾。正则表达式^\W*应与开头的所有非字母数字字符匹配,并与结尾的\W*$匹配。您可以简单地将这些正则表达式替换为空字符串以摆脱非字母数字字符。显然,您必须对Java字符串中的\进行转义(假设您正在使用Java)。