有没有办法在PHP正则表达式中指定“任何字符但[aeiou]”?

时间:2011-04-07 17:06:16

标签: php regex regex-negation

我正在开发一个C#Web服务,它的响应始终是事物的集合。由于我太懒了而且不想明确定义事物的集合,我实现了一个泛型类,表示可以使用XML序列化的东西的集合。

现在,ASP.NET通常会为泛型提供可怕的名称,例如CollectionOfOrdenPago(西班牙语,“orden de pago”表示“付款顺序”)或PageOfLineaDetalleReporte(西班牙语,“líneade” detalle de reporte“means”报告细节线“)。我想给我的馆藏更合理的名称,如OrdenesPago(“付款订单”)或LineasDetalleReporte(“报告明细行”),所以我定义了以下方法:

internal static string Pluralize(string input)
{
    int i = 0;
    while (++i < input.Length)
        if (!char.IsLower(input[i]))
            break;

    StringBuilder builder = new StringBuilder(input);
    if ("aeiou".IndexOf(input[i - 1]) == -1)
        builder.Insert(i++, 'e');
    builder.Insert(i, 's');

    return builder.ToString();
}

此Web服务由PHP网站使用,我也在开发。由于复制名词似乎不是调用C#Web服务的好理由,我在PHP中重新实现了Pluralize函数:

function pluralize($element) {
    return preg_replace_callback('/^([A-Z][a-z]*)([A-Z]|$)/', function($args) {
        // If the first word ends in consonant, append "e" first. After that, append "s".
        return preg_replace('/([B-DF-HJ-NP-TV-Z])$/i', '\1e', $args[1]) . "s{$args[2]}";
    }, $element);
}

但我仍然不高兴。术语[B-DF-HJ-NP-TV-Z]丑陋的。和C#方法一样,我想指定“不在[aeiou]中的字符”作为术语。这可能吗?

3 个答案:

答案 0 :(得分:11)

使用否定的字符类

[^AEIOU]

而不是[B-DF-HJ-NP-TV-Z]

N.B。根据@fireeyedboy的评论,此正则表达式也匹配非字母字符。

答案 1 :(得分:3)

不确定。插入符号(^)否定了一个字符类:

/[^aeiou]/i

答案 2 :(得分:2)

首先,你的字符串必须是规范化形式D.否则你会错过MaríaÁngelesArgüelles和< EM>波哥大。这是Perl中的一个例子:

#!/usr/bin/env perl
use utf8;
use strict;
use warnings;    
use Unicode::Normalize qw(NFD NFC);    
binmode(STDOUT, ":utf8") || die;    
my @names = qw(María Ángeles Argüelles Bogotá cáñamo);
for my $orig ("@names", @names) {
    my $nfd = NFD($orig);
    $nfd =~ s/( (?: (?! [aeiou] ) (?= \pL ) \X ) +)/<$1>/xig;
    print NFC($nfd), "\n";
}

运行时打印出来:

<M>a<r>ía Á<ng>e<l>e<s> A<rg>üe<ll>e<s> <B>o<g>o<t>á <c>á<ñ>a<m>o
<M>a<r>ía
Á<ng>e<l>e<s>
A<rg>üe<ll>e<s>
<B>o<g>o<t>á
<c>á<ñ>a<m>o

我不知道如何在PHP中引入所需的NFD函数,但是一旦你想出那部分,其余部分应该完全可以转移。