Java 如何使用正则表达式从字符串中删除外部标点

Java 如何使用正则表达式从字符串中删除外部标点,java,regex,string,java.util.scanner,delimiter,Java,Regex,String,Java.util.scanner,Delimiter,给定如下字符串,通过正则表达式删除任何前导和尾随标点符号: 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"; 。。。而不是

给定如下字符串,通过正则表达式删除任何前导和尾随标点符号:

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";

我只需要正则表达式;不是删除标点符号的实际代码。

您可以使用
^
$
^
匹配字符串的开头,而
$
匹配字符串的结尾。正则表达式
^\W*
应在开头匹配所有非字母数字字符,在结尾匹配所有非字母数字字符。您可以简单地用空字符串替换这些正则表达式,以去除非字母数字字符。显然,您必须转义Java字符串中的
\
(假设您正在使用Java)。

您希望匹配与a)空格字符或b)开头或结尾相邻的标点符号

  • 您的模式前面有
    (?)?
    
  • 您的模式后跟
    (?!\S)
    负前瞻

最后,您应该使用
\p{Punct}
而不是
[\p{Alnum}]
来匹配标点符号。有关详细信息,请参阅

下面是一个示例用法:

String a = "!?Don't.;, .:delete !the@ $actual string%";
String b = "Hyphenated-words, too!";
String regex = "(?:(?<!\\S)\\p{Punct}+)|(?:\\p{Punct}+(?!\\S))";
System.out.println(a.replaceAll(regex, ""));
System.out.println(b.replaceAll(regex, ""));
String a=“!?不;,:删除@$actual String%”;
String b=“连字符的单词也是!”;

String regex=“(?:(?您可以使用以下正则表达式:

代之以

1美元

对于示例输入,输出为:

不要删除实际字符串
连字符的单词也是


注意:我已经使用了
\w
,但是如果您需要更精确的字母数字定义,那么用
\p{Alnum}
替换这两个
\w
,在punct和Alnum之后可能没有多少剩余(除了ctrl的)。
也可以通过使用空白边界来利用这一点

查找:
原始
(?

字符串
”(?当你说“前导”和“尾随”时,这不是意味着结果应该是
不。;,:delete!@$actual字符串
?什么是“前导”或“尾随”例如,关于
@
,它不适用于
中的
,顺便说一句,请求正则表达式就是请求代码。不要这样做。@realpoint我的意思是“前导”/“尾随”字符串中每个单词的标点符号,不一定是字符串本身的标点符号。我没有明确指出我使用的是扫描定界符(这就是为什么我只需要正则表达式,而不是整个代码本身)。至于你最后的评论,我不知道要求一个正则表达式就是要求代码;我提前表示歉意。你想要得到什么结果?a=“不要删除实际字符串”;b=“连字符的单词太多”;或这a=“不要删除实际字符串”;b=“连字符的单词太多”@J.Adder我已经更新了我的答案,使用
\p{Punct}
现在,根据sln的评论,这仍然是一件小事,比如这个连字符--words!我相信你能做好luck@YCF_L您希望输入“连字符--words,too!”的输出是什么?我的理解是“--”不是引导或拖尾这个词,而是在词的中间,因此应该保持不变。也考虑“麦克-道格尔”。请更好地解释你想要什么。哦,好吧,这是我的坏,那么,你就可以得到我的投票权。这是一个不完整的解决方案。<代码> \p{ Alnum }。
还包括所有空白,这有效地去除了所有格式和其他大量非标点的Unicode代码点。如果要使用这种方法,至少要排除空白
(?:(?@sln很好。我假设OP想使用
[\P{Alnum}]
但仔细检查后,这是一个可怕的假设。注意:由于OP希望将regex用作“扫描仪定界符”,因此他无法直接使用任何涉及
$1
或类似内容的答案。
 (?<! \S )                             # Whitespace boundary
 (?:                                   # 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