正则表达式通过空格,标点符号,换行符将文本分成数组

时间:2013-11-12 11:34:06

标签: php regex

我需要通过空格,标点符号,换行符将文本分成数组。以下是示例文本:

  

男士夹克是绿色的。   他 - 现代历史上最大的明星 - 骑自行车的速度非常快(每小时230公里)。这怎么可能?!他用的是什么样的自行车?   他的自行车的半自动装备相当昂贵,显着有助于达到这个速度。一些(或许可能很多)声称他是世界上最快的! “我看到他骑自行车!”约翰迪尔先生说。 “他设定的速度是每小时133.78公里,”听起来令人难以置信;听起来很有欺骗性。

我已经获得了regex that does that

preg_split('/(?<=\s)|(?<=\w)(?=[.,:;!?()-])|(?<=[.,!()?\x{201C}])(?=[^ ])/u', $text);

但是目前它将以下semi-automatic分成两个单词,而它必须保持为一个单词。如果除了semi - automatic之外还有空格,那么这应该是三个单词。我不太明白这个正则表达式是如何工作的,所以感谢任何帮助。

第二个问题是,如果文本包含换行符,它会捕获换行符,但也会创建冗余元素。参见example - 元素[8]和[9]。元素[8]是多余的。我该如何解决它?

2 个答案:

答案 0 :(得分:1)

我没有测试以下内容。

首先让我们改变正则表达式:

/[.,:;!?()\s]|(?<=\s)-(?=\s)/u

说明:

[.,:;!?()\s] - 在标点符号上拆分

|(?<=\s)-(?=\s) - (替代)拆分- -

两侧的空格

接下来,对结果执行array_filter(),删除空| false元素

编辑:

要使用标点符号:

/(?=[.,:;!?()\s])|(?<=\s)-(?=\s)/u

我只是用一个先行

包围了角色类

编辑2:

/\s|(?=[.,:;!?)])|(?<=\s[("])|(?<=\s)-(?=\s)/u

编辑3:

\s|(?<=\s)-(?=\s)|(?<=\w)(?=[.,:;!?])|(?<=[.,"!()?\x{201C}])(?=[^ ])

编辑4:

\s|(?<=\s)-(?=\s)|(?<=\w)(?=[.,:;!?)])|(?<=[.,"!()?\x{201C}])(?=[^ ])

<强>解释说:

哦,我的,我的脑袋今天不在游戏中。你的正则表达式几乎就在那里,只需要一两个mod,所以这里是最终的正则表达式。

/\s|(?<=\w)(?=[.,:;!?)])|(?<=[.,"!()?\x{201C}])/u

注意:lookarounds只匹配某些内容,它们消耗零个字符,因此您可能遇到“零宽度断言”术语。如果我们没有使用lookarounds,则正则表达式引擎将匹配该字符并将其从匹配项中删除。管道元字符|OR,正则表达式为alternate模式。

\s - 匹配空格字符。我们不需要这样做,因为我们想要删除它。

(?<=\w)(?=[.,:;!?)]) - 或者匹配单词字符\w的正向lookbehind,然后是以下任何标点符号.,:;!?)的正向前瞻。

(?<=[.,"!()?\x{201C}]) - 或者与以下标点字符.,"!()?\x{201C}的正向后视匹配。 \x{201C}是左双引号(unicode双字节字符)。

u - 修饰符,允许使用utf-8字符,例如\x{201C}

在原始正则表达式中,(?=[^ ])最后是多余的,所以我删除了它。它本来可以写成(?!\s),它是相同的,是单个空白字符的负前瞻。

所以你要使用preg_split()之类的:

$return = preg_split('/\s|(?<=\w)(?=[.,:;!?)])|(?<=[.,"!()?\x{201C}])/u', $text, -1, PREG_SPLIT_NO_EMPTY)

答案 1 :(得分:0)

你可以试试这个:

preg_split('/[^\PP.-]|(?<=\s)-(?=\s)|\s+|\.(?!\d)/u', $str, null, PREG_SPLIT_NO_EMPTY);