【问题标题】:Find Lowercase immediately followed by uppercase查找小写字母后跟大写字母
【发布时间】:2012-01-08 04:38:06
【问题描述】:

我的文字如下:

<font size=+2 color=#F07500><b> [ba]</font></b>
<ul><li><font color =#0B610B> Word word wordWord word.<br></font></li></ul>
<ul><li><font color =#F07500> Word word word.<br></font></li></ul>
<ul><li><font color =#0B610B> Word word word wordWord.<br></font></li></ul>
<ul><li><font color =#0B610B> WordWord.<br></font></li></ul>
<br><font color =#E41B17><b>UPPERCASE LETTERS</b></font> 
<ul><li><font color =#0B610B> Word word wordWord word.<br></font><br><font color =#E41B17><b>PhD and dataBase</b></font> </li></ul>
<font color =#0B610B> Word word word.<br></font></li></ul><dd><font color =#F07500>     »» Word wordWord word.<br></font>

每个&lt;font color =#0B610B&gt;...&lt;/font&gt; 中都有一个小写字母紧跟一个大写字母。例如:

<font color =#0B610B> Word word wordWord word.<br></font>

我想通过如下拆分它们来纠正这个错误(即:在它们之间添加一个冒号和一个空格):

<font color =#0B610B> Word word word: Word word.<br></font>

到目前为止,我一直在使用:

(<font color =#0B610B\b[^>]*>)(.*?</font>)

选择&lt;font color =#0B610B&gt;...&lt;/font&gt;的每个实例,它可以很好地找到&lt;font color =#0B610B&gt;...&lt;/font&gt;的一个实例。

但是当我使用时:

(<font color =#0B610B\b[^>]*>)(.*?[a-z])([A-Z].*?</font>)

不管其他字体颜色标签如何,它都会找到但选择一行中&lt;font color =#0B610B&gt;...&lt;/font&gt;之间的所有内容,并替换其他不需要的实例。

我希望它找到并替换每个特定标签对中的错误:&lt;font color =#0B610B&gt;...&lt;/font&gt;,而不是抓取从 &lt;font color =#0B610B&gt; 开始并以 &lt;/font&gt; 结束的所有内容

有没有正则表达式可以解决这个问题?非常感谢。

【问题讨论】:

    标签: regex text grep textwrangler


    【解决方案1】:

    一般来说,正则表达式不是解析 HTML 的好主意(如果它是一次性的,你可能还可以)。

    我认为这可能是您的正则表达式不起作用的原因。 你能举一个你的正则表达式失败的例子吗?

    我能想到的一种情况是,在匹配的 &lt;font color=#0B610B&gt;&lt;/font&gt; 对中没有匹配 ([a-z][A-Z]),但在相邻的 &lt;font&gt;&lt;/font&gt; 中有 。例如:

    <font color=#0B610B>word word</font><font color=#000000>word wordWord</font>
    

    在这种情况下,只有有效匹配是&lt;font color=#0B610B&gt;word word&lt;/font&gt;&lt;font color=#000000&gt;word word和字符串的其余部分Word&lt;/font&gt;,所以这就是正则表达式匹配的内容(因为如果它可以匹配它!)

    我可以想到一个粗略的解决方法,但我不会推荐它,除非这个任务是一次性的,因为对 HTML 使用正则表达式总是容易出现这样的错误!。这个正则表达式也非常低效。尝试(未经测试):

    (<font color =#0B610B\b[^>]*>)(([^<]|<(?!/font))*?[a-z])([A-Z].*?</font>)
    

    它说,“查找&lt;font colour=xxxx&gt; 标签,然后是尖括号&lt; 不是,然后是/font,或者其他任何东西,然后再是[a-z][A-Z] ”。 因此它会尝试确保匹配不会超出&lt;/font&gt; 边界。

    【讨论】:

    • 非常感谢 math.coffee。我想这会对我有所帮助,因为它似乎找到了我想要的东西,但是当被\1\2: \3\4 替换时,匹配变为&lt;font color=#0B610B&gt;Word word: xWord&lt;/font&gt;。不知道为什么这里要加字符xx可以是任意字母)。
    • 那是因为有一个额外的内部捕获括号,\3 包含一个字符。请注意\2 包围\3,因此请替换为\1\2: \4
    • 太棒了!你救了我的命,mathical.coffee。它现在就像一个魅力。非常感谢。