我正在使用Text::Ngrams
来确定字符串中的单词组合。但是,我需要保留带有数字的单词。我已经确定$o->{tokenrex}
是我需要修改的内容,但我无法确定它的正确正则表达式。
原作是qr/([a-zA-Z]+|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/;
,但我认为我还需要更多内容:
qr/([a-zA-Z]+|(?<=\w)(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?(?=\w)|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/;
如果我正在阅读正则表达式,那么应该匹配任意数量的字母字符,或者在它之前和之后具有单词字符的“数字”,或者“数字”。除了它将我的“单词”分成单独的标记。我正在使用的示例单词是“ A1X ”。
任何帮助都会很棒。
答案 0 :(得分:4)
你们这些都太复杂了。原始正则表达式匹配仅由字母或数字组成的单词(整数,浮点数,包括指数表示法)。
如果您需要匹配由字母和数字组成的单词,那么正则表达式为[a-zA-Z\d]+
。根据模块文档,您还需要指定要跳过的内容,并且匹配[^a-zA-Z\d]+
。
$self->{tokenrex} = qr/([a-z\d]+)/i;
$self->{skiprex} = qr/([^a-z\d]+)/i;
如果您需要识别模块文档中显示的数字,请告诉我,我很乐意为您添加。根据您的描述,这听起来并不像您需要的那样。
答案 1 :(得分:0)
所以看起来你有几件事需要修复。如果我明白你的意思,那么将单词分成不同的标记就很容易了:只使用非捕获组。如果您不想围绕(?:foo)
创建新的捕获组,请使用foo
;如果你这样做,请使用(foo)
。
无论如何,你想要的模式对我来说是这样的:
p{L}*(?:\d*\.)?\d+(?:[eE][-+]?\d+)?(?:(?<=p{L}(?:\d*\.)?\d+(?:[eE][-+]?\d+)?)p{L}+)?
说明:
p{L}* #Zero or more letter characters (note that this is broader than [a-zA-Z], as it allows accent marks and so forth)
(?:\d*\.)?\d+ #Slightly simplified version of your number-matching pattern
(?:(?<=p{L}...)p{L}+)? #Optionally match trailing letters, but only if there are letters at the beginning
希望我明白你在寻找什么。一个问题是[eE]
;这将引入一些含糊之处。例如,如果你得到一个像 A3E4D 这样的字符串,那么E是一个字母还是一个指数?我对此有一些想法,但它会更长,更复杂。让我知道规则是什么,我会编辑,我只是不想让这更令人困惑,直到我确定你在寻找什么。
答案 2 :(得分:0)
(?<=...)
和(?=...)
构造是后视和前瞻表达式,它们匹配的文本不包含在与整个常规匹配的文本中表达。
作为一个更简单的例子,对于$_ = "A1X"
,正则表达式
qr/(?<=A)1(?=X)/
与字符串$_
匹配,但与表达式匹配的文字(例如,在$&
中)只是1
,而不是A1X
。
您可以在原始表达式中添加另一个子句:
qr/([a-zA-Z]+|[a-zA-Z][a-zA-Z0-9]+[a-zA-Z]|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/
(这将与A1B2C3D
相匹配 - 目前尚不清楚你是否希望它这样做)
答案 3 :(得分:0)
试试这个:
qr/(\b[a-zA-Z]([a-zA-Z\d]+[a-zA-Z])?\b|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/
但请注意,此正则表达式(和原始版本)将匹配单词“边缘”上的数字。