2012-07-06 12 views
6

तो, मैं नियमित अभिव्यक्तियों को समझना शुरू कर रहा हूं और मुझे सीखने की वक्र काफी हद तक मिल गई है। हालांकि, मेरे प्रयोग की प्रक्रिया में स्टैक ओवरफ्लो बेहद सहायक रहा है। एक विशेष शब्द मैक्रो है जिसे मैं लिखना चाहता हूं लेकिन मुझे ऐसा करने का कोई तरीका नहीं पता है। मैं दस्तावेज़ में एक दूसरे के शब्दों के दो या दो शब्दों के भीतर दो शब्दों को खोजने में सक्षम होना चाहता हूं और फिर उन शब्दों को इटैलिक कर सकता हूं, यदि शब्द 10 से अधिक शब्द अलग हैं या एक अलग क्रम में हैं, तो मै मैक्रो को इटैलिकिस करना नहीं चाहता वो शब्दरेगेक्स वर्ड मैक्रो जो दो शब्दों को एक-दूसरे की सीमा के भीतर पाता है और फिर उन शब्दों को इटैलिक करता है?

मैं निम्नलिखित नियमित अभिव्यक्ति का उपयोग किया गया:

\bPanama\W+(?:\w+\W+){0,10}?Canal\b 

हालांकि यह केवल मेरे बीच में यादृच्छिक शब्दों सहित एक समग्र रूप से पूरी स्ट्रिंग में हेरफेर करने देता है। इसके अलावा। Resplace फ़ंक्शन केवल मुझे उस स्ट्रिंग को एक अलग स्ट्रिंग के साथ बदलने देता है जो स्वरूपण शैलियों को नहीं बदलता है।

क्या किसी और अनुभवी व्यक्ति को यह विचार है कि यह काम कैसे करें? क्या यह करना भी संभव है?


संपादित करें: यहाँ क्या मैं अब तक है। मेरे पास दो समस्याएं हैं I सबसे पहले मुझे नहीं पता कि मिलान किए गए नियमित अभिव्यक्ति के भीतर से केवल "पनामा" और "नहर" शब्द का चयन कैसे करें और केवल उन शब्दों को बदलें (और मध्यवर्ती शब्द नहीं)। दूसरा, मुझे नहीं पता कि एक रेगेक्स को कैसे बदला जाए, जो किसी भिन्न प्रारूप से मेल खाता है, केवल टेक्स्ट की एक अलग स्ट्रिंग - संभवतः शब्द मैक्रोज़ के साथ परिचितता की कमी के परिणामस्वरूप।

Sub RegText() 
Dim re As regExp 
Dim para As Paragraph 
Dim rng As Range 
Set re = New regExp 
re.Pattern = "\bPanama\W+(?:\w+\W+){0,10}?Canal\b" 
re.IgnoreCase = True 
re.Global = True 
For Each para In ActiveDocument.Paragraphs 
    Set rng = para.Range 
    rng.MoveEnd unit:=wdCharacter, Count:=-1 
    Text$ = rng.Text + "Modified" 
    rng.Text = re.Replace(rng.Text, Text$) 
Next para 
End Sub 

ठीक है, टिम विलियम्स से मदद करने के लिए नीचे दिए गए मैं निम्नलिखित समाधान एक साथ मिल गया धन्यवाद, यह कुछ मामलों में एक छोटे से अधिक से अधिक अनाड़ी है और यह कोई शुद्ध regexp तरह से है, लेकिन इसे मिल करता है काम हो गया। अगर किसी के पास इस बारे में बेहतर समाधान या विचार है कि इस बारे में कैसे जाना है, तो मैं इसे सुनने के लिए मोहक हूं। फिर, मेरे जानवर खोज के साथ परिवर्तन के लिए मजबूर और सुविधा की जगह एक छोटे से शर्मनाक कच्चे है लेकिन कम से कम यह काम करता है ...

Sub RegText() 
Dim re As regExp 
Dim para As Paragraph 
Dim rng As Range 
Dim txt As String 
Dim allmatches As MatchCollection, m As match 
Set re = New regExp 
re.pattern = "\bPanama\W+(?:\w+\W+){0,13}?Canal\b" 
re.IgnoreCase = True 
re.Global = True 
For Each para In ActiveDocument.Paragraphs 

    txt = para.Range.Text 

    'any match? 
    If re.Test(txt) Then 
    'get all matches 
    Set allmatches = re.Execute(txt) 
    'look at each match and hilight corresponding range 
    For Each m In allmatches 
     Debug.Print m.Value, m.FirstIndex, m.Length 
     Set rng = para.Range 
     rng.Collapse wdCollapseStart 
     rng.MoveStart wdCharacter, m.FirstIndex 
     rng.MoveEnd wdCharacter, m.Length 
     rng.Font.ColorIndex = wdOrange 
    Next m 
    End If 

Next para 

Selection.Find.ClearFormatting 
Selection.Find.Font.ColorIndex = wdOrange 
Selection.Find.Replacement.ClearFormatting 
Selection.Find.Replacement.Font.Italic = True 
With Selection.Find 
    .Text = "Panama" 
    .Replacement.Text = "Panama" 
    .Forward = True 
    .Wrap = wdFindContinue 
    .Format = True 
    .MatchCase = False 
    .MatchWholeWord = False 
    .MatchWildcards = False 
    .MatchSoundsLike = False 
    .MatchAllWordForms = False 
End With 
Selection.Find.Execute Replace:=wdReplaceAll 
Selection.Find.ClearFormatting 
Selection.Find.Font.ColorIndex = wdOrange 
Selection.Find.Replacement.ClearFormatting 
Selection.Find.Replacement.Font.Italic = True 
With Selection.Find 
    .Text = "Canal" 
    .Replacement.Text = "Canal" 
    .Forward = True 
    .Wrap = wdFindContinue 
    .Format = True 
    .MatchCase = False 
    .MatchWholeWord = False 
    .MatchWildcards = False 
    .MatchSoundsLike = False 
    .MatchAllWordForms = False 
End With 
Selection.Find.Execute Replace:=wdReplaceAll 

Selection.Find.ClearFormatting 
Selection.Find.Font.ColorIndex = wdOrange 
Selection.Find.Replacement.ClearFormatting 
Selection.Find.Replacement.Font.ColorIndex = wdBlack 
With Selection.Find 
    .Text = "" 
    .Replacement.Text = "" 
    .Forward = True 
    .Wrap = wdFindContinue 
    .Format = True 
    .MatchCase = False 
    .MatchWholeWord = False 
    .MatchWildcards = False 
    .MatchSoundsLike = False 
    .MatchAllWordForms = False 
End With 
Selection.Find.Execute Replace:=wdReplaceAll 
End Sub 
+0

मैच ऑब्जेक्ट में एक इंडेक्स प्रॉपर्टी है जो आपको बताती है कि मैच में टेक्स्ट कहां हुआ था। आप अपने स्वरूपण को बदलने के लिए विशेष श्रेणियों को संबोधित करने के लिए इसका उपयोग कर सकते हैं। यदि आप अपना मौजूदा कोड दिखाने के लिए अपना प्रश्न अपडेट करते हैं तो कोई सुझाए गए परिवर्तनों के साथ झुका सकता है। –

+0

मुझे उन शब्दों की सूची दिखाएं जिन्हें आप रेगेक्स चालू कर रहे हैं। – jared

+1

क्या यह शब्द '10 से अधिक शब्द' हैं या 'शब्द 10 से अधिक अक्षर हैं 'या' वाक्य 10 से अधिक शब्द हैं'? – Cylian

उत्तर

6

मैं एक लंबा रास्ता बंद किया जा रहा हूँ है, कई शताब्दियों के लिए चारों ओर हो गया है समय से लोगों को इस अवधि में एक सभ्य शब्द प्रोग्रामर, लेकिन यह आपको शुरू हो सकता है।

संपादित करें: एक पैरामीटर संस्करण शामिल करने के लिए अपडेट किया गया।

Sub Tester() 

    HighlightIfClose ActiveDocument, "panama", "canal", wdBrightGreen 
    HighlightIfClose ActiveDocument, "red", "socks", wdRed 

End Sub 


Sub HighlightIfClose(doc As Document, word1 As String, _ 
        word2 As String, clrIndex As WdColorIndex) 
    Dim re As RegExp 
    Dim para As Paragraph 
    Dim rng As Range 
    Dim txt As String 
    Dim allmatches As MatchCollection, m As match 

    Set re = New RegExp 
    re.Pattern = "\b" & word1 & "\W+(?:\w+\W+){0,10}?" _ 
       & word2 & "\b" 
    re.IgnoreCase = True 
    re.Global = True 

    For Each para In ActiveDocument.Paragraphs 

     txt = para.Range.Text 

     'any match? 
     If re.Test(txt) Then 
     'get all matches 
     Set allmatches = re.Execute(txt) 
     'look at each match and hilight corresponding range 
     For Each m In allmatches 
      Debug.Print m.Value, m.FirstIndex, m.Length 
      Set rng = para.Range 
      rng.Collapse wdCollapseStart 
      rng.MoveStart wdCharacter, m.FirstIndex 
      rng.MoveEnd wdCharacter, Len(word1) 
      rng.HighlightColorIndex = clrIndex 
      Set rng = para.Range 
      rng.Collapse wdCollapseStart 
      rng.MoveStart wdCharacter, m.FirstIndex + (m.Length - Len(word2)) 
      rng.MoveEnd wdCharacter, Len(word2) 
      rng.HighlightColorIndex = clrIndex 
     Next m 
     End If 

    Next para 

End Sub 
+0

यह टेक्स्ट ढूंढने और उसके प्रारूप को बदलने में बहुत अच्छा काम करता है, मेरे पास असली समस्या यह है कि मैं जो मैक्रोज़ करता हूं वह केवल पूरे वाक्यांशों को बदल सकता है (केवल शब्दों "पैनामा" और "नहर" के बजाय)। तो उदाहरण के लिए उपर्युक्त मैक्रो केवल उस शब्द के 2 और अंतिम शब्द के बजाय "नहर की पनामा परियोजना" में सभी शब्दों को हाइलाइट करता है, यह हो सकता है कि मैं जो करने की कोशिश कर रहा हूं वह असंभव है ... – pavja2

+0

नहीं असंभव: मैंने अभी आपके लिए पूरी चीज नहीं की :-) आप जानते हैं कि पहला शब्द पैनामा होगा, इसलिए बस यह बताएं कि (आप जानते हैं कि यह कहां से शुरू होता है, और इसकी लंबाई)। आखिरी शब्द नहर है, इसलिए बस उस पर भी प्रकाश डालें। इस बिंदु पर बस मूल गणित ... –

+0

हाँ, मैंने वास्तव में इसके चारों ओर एक रास्ता तय किया - यह बहुत ही सुंदर नहीं है लेकिन मैं इसे अपने मूल प्रश्न में पोस्ट कर दूंगा, मैं इसे सभी तरह से काम कर रहा हूं। मदद के लिए धन्यवाद, यह वही है जो मैं खोज रहा था। – pavja2

0

तुम सिर्फ एक समय में प्रत्येक 2 शब्द करने के बाद कर रहे हैं, इस के लिए काम किया मैं, अपनी अभ्यास लाइनों का पालन करें।

foo([a-zA-Z0-9]+?){0,10}bar 

स्पष्टीकरण: शब्द 1 (foo) हड़पने जाएगा, तो कुछ भी अक्षरांकीय वर्णों का एक शब्द ([a-zA-Z0-9]+?) एक अंतरिक्ष (), 10 बार ({0,10}), तो शब्द 2 द्वारा पीछा किया है कि मेल खाते हैं (bar)।

यह पूर्ण विराम (यदि आप उन्हें चाहता था पता नहीं था) को शामिल नहीं करता है, लेकिन तुम सिर्फ regex में 0-9 के बाद . जोड़ना चाहते हैं।

तो अपने (स्यूडोकोड) वाक्य रचना हो जाएगा करने के लिए समान:

$matches = preg_match_all(); // Your function to get regex matches in an array 

foreach (those matches) { 
    replace(KEY_WORD, <i>KEY_WORD</i>); 
} 

उम्मीद है कि यह मदद करता है। नीचे परीक्षण, यह क्या मिलान किया हाइलाइट किया।


काम किया:

foo this that bar blah

foo economic order war bar

foo आर्थिक व्यवस्था काम नहीं किया। युद्ध बार

वैश्विक foo आदेश अलग और जटिल व्यापार कृषि के रूप में स्थितियों से निपटने रिश्ते विकसित और बार

+0

शायद मुझे कुछ याद आ रहा है, मेरी समस्या यह है कि मैं केवल पूरे रेगेक्स मैच को बदल सकता हूं (यानी "foo" और "bar" के बीच के सभी शब्द भी बदले गए हैं)। मुझे नहीं पता कि मैचों को कैसे लेना है और फिर मिलान किए गए पाठ के भीतर किसी अन्य शब्द को प्रभावित किए बिना केवल "foo" और "bar" शब्द को बदलें। एक माध्यमिक समस्या जो मेरे पास अच्छा Google-fu या VBA मैक्रोज़ के साथ परिचितता का नतीजा नहीं है, यह है कि मुझे नहीं पता कि मिलान किए गए Regexp के प्रारूप को कैसे बदला जाए, बस सामग्री को कैसे बदला जाए। मैंने मैक्रो के साथ अपना प्रश्न अपडेट किया है जिसके साथ मैं वर्तमान में काम कर रहा हूं। – pavja2

संबंधित मुद्दे

 संबंधित मुद्दे