【问题标题】:Match a word using regex that also handles apostrophes使用也处理撇号的正则表达式匹配单词
【发布时间】:2012-11-29 18:53:06
【问题描述】:

我必须将一行文本分成单词,并且对使用什么正则表达式感到困惑。 我到处寻找一个匹配一个单词的正则表达式,并找到了与这篇文章类似的正则表达式,但在 java 中需要它(java 不处理常规字符串中的 \)。

Regex to match words and those with an apostrophe

我已经为每个答案尝试了正则表达式,但不确定如何为此构建 Java 正则表达式(我假设所有正则表达式都是相同的)。如果在我看到的正则表达式中将 \ 替换为 \,则正则表达式不起作用。

我也尝试过自己查找并来到此页面: http://www.regular-expressions.info/reference.html

但我无法完全理解正则表达式的高级技术。

我正在使用 String.split(regex string here) 来分隔我的字符串。 一个例子是,如果我得到以下信息: “我喜欢吃,但我不喜欢吃每个人的食物,否则他们会饿死。” 我要匹配:

I
like
to
eat
but
I
don't
like
to
eat
everyone's
food
or
they'll
starve

我也不想匹配 '' 或 '''' 或 ' ' 或 '.'' 或其他排列。 我的分隔符条件应该类似于: [匹配任何单词字符][如果撇号前面有单词字符,也匹配撇号,如果有则匹配它后面的单词字符]

我得到的只是一个匹配单词 [\w] 的简单正则表达式,但我不确定如何使用前瞻或后视来匹配撇号,然后匹配剩余的单词。

【问题讨论】:

  • 为什么不在空白处分割? yourString.split("\\s+");
  • @Alex 不是真的,他问的是同一个问题,但用的是不同的语言。 (Python 3.x vs Java)会有不同的答案。
  • @Alex 不,他说他尝试了该问题中的所有答案,但他问的是如何让 Java 正则表达式匹配带有撇号的单词。 Python 和 Java 实现 Regex 的方式不同,因此表达式的调用方式会略有不同。如果有人不熟悉这两种语言,在两者之间翻译正则表达式可能不是直截了当的。例如,并非所有语言都支持 Look-behinds,因此表达式会有所不同。
  • 正则表达式 "\\w+('\\w+)*'?"似乎删除了除标点符号等之外的所有单词。我给了它一句话“你好,世界!不要吃别人的三明治。人民”。它给出(由-分隔):“”-”,“-”!“-”“-”“-”“-”。“-”。这似乎正确地选择了分隔符,但我如何让它得到单词?

标签: java regex split word apostrophe


【解决方案1】:

使用我评论中所述页面上WhirlWind 的回答,您可以执行以下操作:

String candidate = "I \n"+
    "like \n"+
    "to "+
    "eat "+
    "but "+
    "I "+
    "don't "+
    "like "+
    "to "+
    "eat "+
    "everyone's "+
    "food "+
    "''  ''''  '.' ' "+
    "or "+
    "they'll "+
    "starv'e'";

String regex = "('\\w+)|(\\w+'\\w+)|(\\w+')|(\\w+)";
Matcher matcher = Pattern.compile(regex).matcher(candidate);
while (matcher.find()) {
  System.out.println("> matched: `" + matcher.group() + "`");
}

它将打印:

> matched: `I`
> matched: `like`
> matched: `to`
> matched: `eat`
> matched: `but`
> matched: `I`
> matched: `don't`
> matched: `like`
> matched: `to`
> matched: `eat`
> matched: `everyone's`
> matched: `food`
> matched: `or`
> matched: `they'll`
> matched: `starv'e`

您可以在此处找到一个运行示例:http://ideone.com/pVOmSK

【讨论】:

  • 它似乎在 java String.split(String s) 方法中不起作用。我得到空字符串和其他一些分隔符。这是我的代码的屏幕截图和来自 BlueJ 的结果:i1186.photobucket.com/albums/z379/Richard_Duerr/regexProb.png
  • 我试图“反转”这些条件,因为 Split 正在寻找分隔符,所以我希望分隔符不是任何数量的单词字符后面或前面有撇号,其中撇号是可选的。
  • 我认为这个正则表达式非常接近:"[^a-zA-Z0-9']+" 它适用于所有情况,除了撇号位于一系列字母数字之后。跨度>
  • 如果您想查找还包含撇号的单词,您不能只使用简单的分隔符。 [^a-zA-Z0-9']+ 表示它将拆分除字母数字和撇号之外的任何内容(重复),但它不会拆分其中包含多个撇号的内容。如果你觉得很好,那就去吧。
  • 这会破坏像“T-Mobile”或“U.K.”这样的词一分为二。这是一个处理该问题的正则表达式:"Hey y'all, use T-Mobile & 23andme.com in the U.K.! Thanks.".match(/[\w'-.]+\w|[\w'-]+\s*/g)
【解决方案2】:

以下正则表达式似乎正确地涵盖了您的示例字符串。但它不包括撇号的场景。

[\s,.?!"]+

Java 代码:

String input = "I like to eat but I don't like to eat everyone's food, or they'll starve.";
String[] inputWords = input.split("[\\s,.?!]+");

如果我理解正确,撇号应该放在一个单词字符之后。下一个正则表达式应涵盖上述内容以及撇号的特殊情况。

(?<!\w)'|[\s,.?"!][\s,.?"'!]*

Java 代码:

String input = "I like to eat but I don't like to eat everyone's food, or they'll starve.";
String[] inputWords = input.split("(?<!\\w)'|[\\s,.?\"!][\\s,.?\"'!]*");

如果我在字符串上运行第二个正则表达式:Hey there! Don't eat 'the mystery meat'. 我在字符串数组中得到以下单词:

Hey
there
Don't
eat
the
mystery
meat'

【讨论】:

  • 这会破坏像“T-Mobile”或“U.K.”这样的词一分为二。这是一个处理该问题的正则表达式:"Hey y'all, use T-Mobile &amp; 23andme.com in the U.K.! Thanks.".match(/[\w'-.]+\w|[\w'-]+\s*/g)
猜你喜欢
  • 2023-04-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
相关资源
最近更新 更多