英文:
Replacing space after number with hard space in p tag
问题
I would like to replace a space after a number with hard-space " " only in p tags.
I wrote this code:
$pattern = "/<p>[0-9] <\/p>/";
return preg_replace($pattern, "$1 ", $text);
But it does nothing, why? Can you please help?
Example:
Input : "My 90 days work."
Output: "My 90 days work."
Thank you a lot.
英文:
I would like to replace a space after a number with hard-space " " only in p tags.
I wrote this code:
$pattern = "/<p>[0-9] <\/p>/";
return preg_replace($pattern, "$1&nbsp;", $text);
But it does nothing, why? Can you please help?
Example:
Input : "My 90 days work."
Output: "My 90&nbsp;days work."
Thank you a lot.
答案1
得分: 1
$text = '<p>My 90 days 123 work.</p>';
$pattern = "/<p>(.*?)<\/p>";
$text = preg_replace_callback($pattern, function ($matches) {
$content = $matches[1];
$content = preg_replace('/(\d+)\s/', '$1&nbsp;', $content);
return "<p>{$content}</p>";
}, $text);
英文:
Try this:
$text = '<p>My 90 days 123 work.</p>';
$pattern = "/<p>(.*?)<\/p>/";
$text = preg_replace_callback($pattern, function ($matches) {
$content = $matches[1];
$content = preg_replace('/(\d+)\s/', '$1&nbsp;', $content);
return "<p>{$content}</p>";
}, $text);
答案2
得分: 1
以下是您要翻译的内容:
匹配HTML使用正则表达式并不建议,但如果在两个尖括号之间没有其他字符,您可以使用一个正则模式并使用\G
锚点来实现:
(?:<p>(?=[^<>]*</p>)|\G(?!^))[^\d<>]*\d+\K\h
解释
(?:
非捕获组<p>(?=[^<>]*</p>)
匹配<p>
并断言没有尖括号在两者之间|
或者\G(?!^)
断言当前位置在前一个匹配的结尾,但不在字符串的开头
)
关闭非捕获组[^\d<>]*
匹配可选的字符,除了<
、>
或数字\d+
匹配1个或更多数字\K
忘记之前匹配的内容\h
匹配一个水平空白字符
$re = ''~(?:<p>(?=[^<>]*</p>)|\G(?!^))[^\d<>]*\d+\K\h~'';
$str = '<p>My 90 days 123 work.</p>';
echo preg_replace($re, "&nbsp", $str);
输出
<p>My 90&nbspdays 123&nbspwork.</p>
或者使用DOMDocument来查找段落,并在匹配到数字和水平空白字符后进行替换:
$str = '<p>My 90 days 123 work.</p>';
$domDoc = new DOMDocument;
$domDoc->loadHTML($str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($domDoc->getElementsByTagName('p') as $p) {
echo preg_replace("/\d\K\h/", "&nbsp", $p->nodeValue);
}
输出
My 90&nbspdays 123&nbspwork.
英文:
Matching html with a regex is not advisable, but if there can be no angle brackets in between, you might get away with a single pattern using the \G
anchor:
(?:<p>(?=[^<>]*</p>)|\G(?!^))[^\d<>]*\d+\K\h
Explanation
(?:
Non capture group<p>(?=[^<>]*</p>)
Match<p>
and assert a closing</p>
without angle brackets in between|
Or\G(?!^)
Assert the current position at the end of the previous match, but not at the start of the string
)
Close the non capture group[^\d<>]*
Match optional chars other than<
or>
or a digit\d+
Match 1+ digits\K
Forget what is matched so far\h
Match a single horizontal whitespace char
See a regex demo and a PHP demo.
$re = '~(?:<p>(?=[^<>]*</p>)|\G(?!^))[^\d<>]*\d+\K\h~';
$str = '<p>My 90 days 123 work.</p>';
echo preg_replace($re, "&nbsp", $str);
Output
<p>My 90&nbspdays 123&nbspwork.</p>
<hr>
Or using DOMDocument to find the paragraphs, and do the replacement after matching a digit and a horizontal whitespace char:
$str = '<p>My 90 days 123 work.</p>';
$domDoc = new DOMDocument;
$domDoc->loadHTML($str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($domDoc->getElementsByTagName('p') as $p) {
echo preg_replace("/\d\K\h/", "&nbsp", $p->nodeValue);
}
Output
My 90&nbspdays 123&nbspwork.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论