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

时间:2017-04-02 18:10:52

标签: 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";

...而不是:

a = "Dont delete the actual string";
b = "Hyphenated words too";

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

4 个答案:

答案 0 :(得分:2)

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

  • 您的模式前面有(?<=^|\s)正面的背后,或

  • 您的模式后跟(?=\s|$)正向前瞻

为了缩短模式,我们可以稍微改写一下,说我们的标点符号块必须a)前面没有一个不是空格的字符或b)后面没有一个不是空格的字符。

  • 您的模式前面有(?<!\S)负面反对,或

  • 您的模式后跟(?!\S)否定前瞻

最后一点,您应该使用\p{Punct}代替[\P{Alnum}]来匹配标点符号。有关详细信息,请参阅comment by sln

以下是一个示例用法:

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

<强>输出:

  

不要删除实际的字符串

     

连字符

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以使用此正则表达式:

(?:[^\w\s]*)(\S*?)[^\w\s]*(?=\s|$)

代替

<强> $ 1

对于您的样本输入,输出为:

  

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

注意:我使用了\w,但如果您需要更准确的字母数字定义,请将\w替换为\p{Alnum}

答案 3 :(得分:0)

在punct和alnum之后可能没有多少剩余(除了ctrl之外) 也可以通过使用空白边界来利用它。

<强>查找
原始import csv class dirList(object): def __init__(self): self.inFile = None return # a dirList object is iterable so that csv.reader can be used def __iter__(self): return self def next(self): line = self.inFile.next() return line def readDirList(self, sourceFile): # read csv file self.infile = open(sourceFile) print type(self) #yup, self is indeed of the right class which DOES have next() method rdr = csv.reader(self) for csvline in rdr: print csvline self.infile.close() return True #---------------------------------------------------------------------- if __name__ == "__main__": # this works as expected mdl = dirList() mdl.inFile = open('tin.csv', 'r') rdr = csv.reader(mdl) for aaa in rdr: print aaa mdl.inFile.close() # when doing the same thing within a method of the object, it fails with: # AttributeError: 'NoneType' object has no attribute 'next' mdl2 = dirList() mdl2.readDirList('tin.csv') sys.exit() #---- contents of file 'tin.csv' is as follows """ a,b,c d,e,f 1,3,4 """
弦乐(?<!\S)(?:\p{punct}*(\p{alnum}+(?:\p{punct}?\p{alnum})*)\p{punct}*|\p{punct}+)(?!\S)

替换 "(?<!\\S)(?:\\p{punct}*(\\p{alnum}+(?:\\p{punct}?\\p{alnum})*)\\p{punct}*|\\p{punct}+)(?!\\S)"

解释

"$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)