我想根据标题中列出的参数拆分一个字符串。我尝试了一些不同的方法,包括使用preg_match,但到目前为止没有太大成功,我觉得可能有一个更简单的解决方案,我还没有找到。
我有一个正则表达式,它与";价格;标题中提到的(见下文(。
/(?=.)£(([1-9][0-9]{0,2}(,[0-9]{3})*)|[0-9]+)?(.[0-9]{1,2})?/
这里有几个例子,我想要的结果是:
示例1:
input: "This string should not split as the only periods that appear are here £19.99 and also at the end."
output: n/a
示例2:
input: "This string should split right here. As the period is not part of a price or at the end of the string."
output: "This string should split right here"
示例3:
input: "There is a price in this string £19.99, but it should only split at this point. As I want it to ignore periods in a price"
output: "There is a price in this string £19.99, but it should only split at this point"
我建议使用
preg_split('~£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?(*SKIP)(*F)|.(?!s*$)~u', $string)
请参阅regex演示。
该模式与您的模式匹配,£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?
和将跳过它与(*SKIP)(*F)
,否则,它将非最终.
与.(?!s*$)
匹配(即使后面有空白字符(。
如果你真的只需要在第一次出现合格点时进行分割,你可以使用匹配方法:
preg_match('~^((?:£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?|[^.])+).(.*)~su', $string, $match)
请参阅regex演示。这里,
^
-匹配字符串起始位置((?:£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?|[^.])+)
-出现一个或多个货币模式或.
字符以外的任何一个字符.
-一个.
字符(.*)
-第2组:字符串的其余部分
要将文本拆分成句子,避免不同的陷阱,如数字中的点或千位分隔符和一些缩写(如etc.
(,最好的工具是intlBreakIterator
,它是为处理自然语言而设计的:
$str = 'There is a price in this string £19.99, but it should only split at this point. As I want it to ignore periods in a price';
$si = IntlBreakIterator::createSentenceInstance('en-US');
$si->setText($str);
$si->next();
echo substr($str, 0, $si->current());
IntlBreakIterator::createSentenceInstance
返回一个迭代器,该迭代器给出字符串中不同句子的索引。
它还考虑了?
、!
和...
。除了数字或价格陷阱之外,它还可以很好地与这种字符串配合使用:
$str = 'John Smith, Jr. was running naked through the garden crying "catch me! catch me!", but no one was chasing him. His psychatre looked at him from the window with a circumspect eye.';
有关IntlBreakIterator
使用的规则的详细信息,请点击此处。
您可以简单地使用以下regex:
.
既然你在第一句话后面只有一个空格(而不是价格(,这应该也同样有效,对吧?