当前位置: 首页 > 知识库问答 >
问题:

正则表达式以匹配特殊字符,但与数字混合的连字符除外

公良昕
2023-03-14

我们目前正在使用[^a-zA-Z0-9]在Java的replace eAll函数中从字符串中删除特殊字符。我们注意到,当连字符与数字混合时,我们需要允许连字符。

不匹配连字符的示例:

  • 1-2-3
  • -1-23-4562
  • --1--2--3--4-
  • --9-a--7
  • 425-12-3456

将匹配连字符的示例:

    < li> - a - b - c 沃尔玛超市

我们认为我们使用这个SO问题作为参考制定了一个正则表达式来满足后一个标准,但我们不知道如何将其与原始正则表达式[^a-zA-Z0-9]结合起来。

我们希望对Lucene搜索字符串执行此操作,因为Lucene的标准标记器在索引时的工作方式:

在连字符处拆分单词,除非令牌中有数字,在这种情况下,整个令牌被解释为产品编号,不拆分。

共有3个答案

慕容典
2023-03-14

这个问题很棘手,因为Java不允许在环顾中无限递归,这基本上是你需要的。如您所见,我已经设置了 100 个字符的限制,如果您希望单词更长,您可以增加该限制。

这应该有效:

(?<![0-9]\S{0,100})[^a-zA-Z](?!\S{0,100}[0-9])|(?<=[0-9]\S{0,100})[^a-zA-Z0-9-](?=\S{0,100}[0-9])

只有一个简单的带有此表达式的replaceAll()才能处理它。

例如,考虑以下输入:

--9-+-a--7 wal-mart

上面的表达式中,违规字符被替换为零长度字符串,将呈现以下输出:

--9--a--7 walmart

你可以在这里试试:http://fiddle.re/ynyu

请注意,此表达式取决于用空格(空格、制表符、换行符等)分隔的单词。其他字符,如逗号和分号,将导致表达式将这两个单词视为一个单词。例如'--9-a-0-, wal-mart'将被视为一个单词。

编辑我之前编辑的最后一段不正确。如果您想包含其他字符作为分隔符,我建议在第一遍中用空格替换它们(例如,将','替换为')。

我主要是一个.NET程序员,否则我会给你使用这种模式的完整Java代码。

帅锦
2023-03-14

你试过这个吗:

[^a-zA-Z 0-9-]

史经业
2023-03-14

你不能用一个正则表达式做到这一点。(嗯...也许用Perl。)

(编辑:好的,你可以用可变长度的负回溯来做到这一点,看起来Java可以(几乎是唯一的!)做到;参见Cyborgx37的答案。无论如何,imo,你不应该用一个正则表达式来做到这一点。:))

您可以做的是将字符串拆分为单词并单独处理每个单词。我的Java非常糟糕,所以这里有一些希望明智的Python:

# Precompile some regex
looks_like_product_number = re.compile(r'\A[-0-9]+\Z')
not_wordlike = re.compile(r'[^a-zA-Z0-9]')
not_wordlike_or_hyphen = re.compile(r'[^-a-zA-Z0-9]')

# Split on anything that's not a letter, number, or hyphen -- BUT dots
# must be followed by whitespace
words = re.split(r'(?:[^-.a-zA-Z0-9]|[.]\s)+', string)

stripped_words = []
for word in words:
    if '-' in word and not looks_like_product_number.match(word):
        stripped_word = not_wordlike.sub('', word)
    else:
        # Product number; allow dashes
        stripped_word = not_wordlike_or_hyphen.sub('', word)

    stripped_words.append(stripped_word)

pass_to_lucene(' '.join(stripped_words))

当我使用'wal-mart1-2-3'运行它时,我得到了'walmart1-2-3'

但是老实说,上面的代码复制了Lucene tokenizer已经在做的大部分事情。我认为您最好将< code>StandardTokenizer复制到您自己的项目中,并根据您的需要进行修改。

 类似资料:
  • 本文向大家介绍正则表达式匹配各种特殊字符,包括了正则表达式匹配各种特殊字符的使用技巧和注意事项,需要的朋友参考一下 写个可以匹配一下各种特殊字符的正则表达式 这个匹配所有键盘上可见的非字母和数字的符号 这个是输入框防止特殊字符勿输入验证,包括键盘上所有特殊字符的英文和中文状态。需要者可以根据自身需求而定!谢谢! [^\w\s]+ 匹配非空 非字母 非数字 即可 1 数字:^[0-9]*$ 2 n位

  • 我有一个类似这样的字符串: 但是我得到了一个 你知道我做错了什么吗?

  • 问题内容: 我有一个带有某些配置值的文本文件。以#开头的注释我试图找到一个正则表达式模式,该模式将找出以#开头的所有行。 因此,示例文件: 我想找到 因为只有这两行以#开头,所以我尝试了以下代码: 但是它总是输出空数组。有人可以帮忙吗? 问题答案: 你忘了多修饰符(你应该 不 使用单线改性剂;也是不区分大小写的修饰符是不必要的,因为还有ungreedy修改): 说明: 允许and 在行的开头/结尾

  • 问题内容: 我很难提出一个正则表达式,该正则表达式实际上会将某些特殊字符列入黑名单。 我需要使用它来验证输入字段中的数据(在Java Web应用程序中)。我们希望允许用户输入任何数字,字母(我们需要包括带重音的字符,例如法语或德语)和一些特殊字符,例如’-。等等 如何将诸如<>%$等的字符列入黑名单? 问题答案: 我只是将角色列入白名单。 使用正则表达式构建黑名单同样简单,但是你可能需要添加更多字

  • 我试图为密码字段创建一个验证,它只允许字符和 时有什么区别,以及哪些字符来自

  • 我能够编写一个正则表达式来验证输入框的以下标准。 至少包含14个字符 正则表达式- 然而,这个正则表达式允许其他未提及的特殊字符。我想限制所有特殊字符,除了这些