1

Working on something similar to Solr's WordDelimiterFilter, but not in Java.

Want to split words into tokens like this:

P90X                 = P, 90, X (split on word/number boundary)

TotallyCromulentWord = Totally, Cromulent, Word (split on lowercase/uppercase boundary)

TransAM              = Trans, AM

Looking for a general solution, not specific to the above examples. Preferably in a regex flavour that doesn't support lookbehind, but I can use PL/perl if necessary, which can do lookbehind.

Found a few answers on SO, but they all seemed to use lookbehind.

Things to split on:

  1. Transition from lowercase letter to upper case letter
  2. Transition from letter to number or number to letter
  3. (Optional) split on a few other characters (- _)

My main concern is 1 and 2.

4

2 回答 2

2

这不是我不想做的事情,但对于挑战,这是一个 javascript 解决方案,您应该能够轻松地将其转换为任何语言:

function split(s) {
    var match;
    var result = [];
    while (Boolean(match = s.match(/([A-Z]+|[A-Z]?[a-z]+|[0-9]+|([^a-zA-Z0-9])+)$/))) {
        if (!match[2]) {
            //don't return non alphanumeric tokens
            result.unshift(match[1]);
        }
        s = s.substring(0, s.length - match[1].length);
    }
    return result;
}

演示

P90X [ 'P', '90', 'X' ]
TotallyCromulentWord [ 'Totally', 'Cromulent', 'Word' ]
TransAM [ 'Trans', 'AM' ]
URLConverter [ 'URL', 'Converter' ]
Abc.DEF$012 [ 'Abc', 'DEF', '012' ]
于 2014-08-22T18:54:21.443 回答
0

此正则表达式应将段落或字符串中的所有单词拆分为标记。
甚至适用于您示例中的简单案例。

全局匹配。此外,如果您想添加其他特定的分隔符,也可以这样做。

   # /(?:[A-Z]?[a-z]+(?=[A-Z\d]|[^a-zA-Z\d]|$)|[A-Z]+(?=[a-z\d]|[^a-zA-Z\d]|$)|\d+(?=[a-zA-Z]|[^a-zA-Z\d]|$))[^a-zA-Z\d]*|[^a-zA-Z\d]+/

   (?:
        [A-Z]? [a-z]+ 
        (?= [A-Z\d] | [^a-zA-Z\d] | $ )
     |  
        [A-Z]+ 
        (?= [a-z\d] | [^a-zA-Z\d] | $ )
     |  
        \d+ 
        (?= [a-zA-Z] | [^a-zA-Z\d] | $ )
   )
   [^a-zA-Z\d]* 
|  
   [^a-zA-Z\d]+ 
于 2014-08-22T19:04:04.343 回答