2010-03-15 2 views
1

Как бы вы использовать регулярное выражение, чтобы написать функции для выполнения следующих действий:Regex для круговой замены

  1. Заменить нижний регистр «а» с прописными и наоборот
    • Если легко расширяемым, сделать это для всех букв
  2. Где слова разделены пробелами и > и < являются специальные маркеры на несколько слов, заменить >word с word< и пороком вер подлежит утверждению
    • Если это помогает, вы можете ограничить ввод таким образом, чтобы все слова были отмечены так или иначе.
  3. Заменить постинкремент (i++;) с прединрементом (++i;) и наоборот. Имена переменных - [a-z]+. Теперь можно предположить, что ввод можно ограничить кучей этих утверждений. Бонус: также уменьшаются.

Также заинтересованы в решениях в других вариантах.


Примечание: это НЕ домашнее задание вопрос. Смотрите также мои предыдущие изыскания по регулярному выражению:

+0

это действительно правильное использование регулярных выражений? –

+0

Не знаю. Я пытаюсь изучить, что это такое и не для. – polygenelubricants

+0

Первым требованием не может быть регулярное выражение. –

ответ

2

Как вы без сомнения собрали, единственный разумный способ сделать такого рода вещи, чтобы сделать все замены в один проход, динамически генерирующий заменяющие строки на основе того, что было сопоставлено.

Java, по-видимому, уникален среди сегодняшних основных языков, не предоставляя удобный способ сделать это, но это можно сделать можно. Вам просто нужно использовать API нижнего уровня, предоставляемый классом Matcher. Вот демонстрация, основанная на окончательном Rewriter классе Эллиот Хьюз:

import java.util.regex.*; 

/** 
* A Rewriter does a global substitution in the strings passed to its 
* 'rewrite' method. It uses the pattern supplied to its constructor, and is 
* like 'String.replaceAll' except for the fact that its replacement strings 
* are generated by invoking a method you write, rather than from another 
* string. This class is supposed to be equivalent to Ruby's 'gsub' when 
* given a block. This is the nicest syntax I've managed to come up with in 
* Java so far. It's not too bad, and might actually be preferable if you 
* want to do the same rewriting to a number of strings in the same method 
* or class. See the example 'main' for a sample of how to use this class. 
* 
* @author Elliott Hughes 
*/ 
public abstract class Rewriter 
{ 
    private Pattern pattern; 
    private Matcher matcher; 

    /** 
    * Constructs a rewriter using the given regular expression; the syntax is 
    * the same as for 'Pattern.compile'. 
    */ 
    public Rewriter(String regex) 
    { 
    this.pattern = Pattern.compile(regex); 
    } 

    /** 
    * Returns the input subsequence captured by the given group during the 
    * previous match operation. 
    */ 
    public String group(int i) 
    { 
    return matcher.group(i); 
    } 

    /** 
    * Overridden to compute a replacement for each match. Use the method 
    * 'group' to access the captured groups. 
    */ 
    public abstract String replacement(); 

    /** 
    * Returns the result of rewriting 'original' by invoking the method 
    * 'replacement' for each match of the regular expression supplied to the 
    * constructor. 
    */ 
    public String rewrite(CharSequence original) 
    { 
    this.matcher = pattern.matcher(original); 
    StringBuffer result = new StringBuffer(original.length()); 
    while (matcher.find()) 
    { 
     matcher.appendReplacement(result, ""); 
     result.append(replacement()); 
    } 
    matcher.appendTail(result); 
    return result.toString(); 
    } 



    public static void main(String... args) throws Exception 
    { 
    String str = ">Foo baR<"; 

    // anonymous subclass example: 
    Rewriter caseSwapper = new Rewriter("[A-Za-z]") 
    { 
     public String replacement() 
     { 
     char ch0 = group(0).charAt(0); 
     char ch1 = Character.isUpperCase(ch0) ? 
        Character.toLowerCase(ch0) : 
        Character.toUpperCase(ch0); 
     return String.valueOf(ch1); 
     } 
    }; 
    System.out.println(caseSwapper.rewrite(str)); 

    // inline subclass example: 
    System.out.println(new Rewriter(">(\\w+)|(\\w+)<") 
    { 
     public String replacement() 
     { 
     return group(1) != null ? group(1) + "<" 
           : ">" + group(2); 
     } 
    }.rewrite(str)); 

    } 
} 
+0

+1 за то, что обратился ко мне в «Переписывать». – polygenelubricants

1

Лучший способ сделать это - использовать регулярное выражение для соответствия и обратный вызов для замены. Например. в Python:

import re 

# First example 
s = 'abcDFE' 
print re.sub(r'\w', lambda x: x.group().lower() 
           if x.group().isupper() 
           else x.group().upper(), s) 
# OUTPUT: ABCdfe 

# Second example 
s = '<abc dfe> <ghe <auo pio>' 
def switch(match): 
    match = match.group() 
    if match[0] == '<': 
    return match[1:] + '>' 
    else: 
    return '<' + match[:-1] 
print re.sub(r'<\w+|\w+>', switch, s) 
# OUTPUT: abc> <dfe ghe> auo> <pio 
+0

Я хочу, чтобы Java разрешала замену. – polygenelubricants

1

Perl, а также с помощью кода в замене:

$\ = $/; 

### 1. 
$_ = 'fooBAR'; 

s/\w/lc $& eq $&? uc $&: lc $&/eg; 

# this isn't a regex but better (in most cases): 
# tr/A-Za-z/a-zA-Z/g; 

print; 
# FOObar 

### 2. 
$_ = 'foo >bar baz<'; 

s/>(\w+)|(\w+)</$1?"$1<":">$2"/eg; 

print; 
# foo bar< >baz 

### 3. 
$_ = 'x; ++i; i--;'; 

s/(--|\+\+)?\b([a-z]\w*)\b(?(1)|(--|\+\+))/$1?"$2$1":"$3$2"/eig; 

print; 
# x; i++; --i; 
Смежные вопросы