2011-03-10 260 views
3

我使用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”。

任何协助将是伟大的。

+3

学习如何使用并喜欢'x'正则表达式修饰符,它允许您在正则表达式中使用空格(空格,制表符,换行符)来格式化 – 2011-03-10 16:45:40

+0

@Eric Strom我完全打算;我想在尝试解释它做什么之前先让它工作:) – 2011-03-10 18:05:01

+0

这就是要点。如果你能看到它的功能,它更容易工作! – ridgerunner 2011-04-03 02:07:06

回答

4

你们都这样做太复杂了。原始正则表达式仅匹配由字母或数字组成的单词(整数,浮点包括指数符号)。

如果您需要匹配由字母和数字组成的单词,那么正则表达式为[a-zA-Z\d]+。根据模块文档,您还需要指定要跳过的内容,并匹配[^a-zA-Z\d]+

$self->{tokenrex} = qr/([a-z\d]+)/i; 
$self->{skiprex} = qr/([^a-z\d]+)/i; 

如果需要的模块文件显示其例如识别数字,那么请让我知道了,我会很高兴地补充说,早在你。从你的描述来看,这听起来不像你所需要的。

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是指字母还是指数?我对此有一些想法,但会更长,更复杂。让我知道规则是什么,我会编辑,我只是​​不想让这更混乱,直到我确定你在找什么。

+0

在我们的例子中,至少假设你的例子中的E是一个字母,而不是指数。顺便说一下,上面的正则表达式会导致perl抱怨“可变长度lookbehind没有实现” – 2011-03-10 18:04:32

+0

@ gms8994 - 啊,这很不幸。它仍然是可行的,它会更长。试试这个:'p {L} +(?:\ d * \。)?\ d +(?:[eE] [ - +]?\ d +)?p {L} + |(?<!p {L} )(?:\ d * \。)?\ d +(?:[eE] [ - +]?\ d +)?(?! p {L})'应该做同样的事情。 – 2011-03-10 19:27:36

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虽然 - 它并不清楚,如果你想让它做)

+0

当然,它不会总是只有3个字符;这就是为什么我试图使它更通用。 – 2011-03-10 18:02:29

0

试试这个:

qr/(\b[a-zA-Z]([a-zA-Z\d]+[a-zA-Z])?\b|(\d+(\.\d+)?|\d*\.\d+)([eE][-+]?\d+)?)/ 

但是请注意,这正则表达式(与原)将在词的“边缘”相匹配的数字。

+0

p.s.这只是暴民解决方案的一个改进。它将前两个选项合并为一个。 – ridgerunner 2011-03-10 18:25:04

相关问题